2

I am attempting to use a delegate method to push a view to another view. The method only works and does not return null for the delegate when this code: [button addTarget:self action:@selector(pushView:) forControlEvents:UIControlEventTouchUpInside]; is changed to [button addTarget:delegate action:@selector(pushViewController:) forControlEvents:UIControlEventTouchUpInside];. Otherwise, the delegate returns null. I believe this is an issue with ARC not retaining ContentViewController in the ViewController. Please help!

Note: I am using ARC

ContentViewController

@class ContentViewController;
@protocol ContentViewControllerDelegate <NSObject>
@required
-(void)pushViewController:(UIViewController *)viewController;
@end

@interface ContentViewController : UIViewController 
{
    __weak id <ContentViewControllerDelegate> delegate;    
}

@property (weak) __weak id <ContentViewControllerDelegate> delegate;

- (void)pushView:(UIViewController *)viewController;

@end


**ContentViewController.m**

#import "ContentViewController.h"

@implementation ContentViewController

@synthesize delegate;

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];

    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];

    button.frame = CGRectMake(0, 300, 250, 30);

    button.backgroundColor = [UIColor grayColor];

    [button setTitle:@"Test Button" forState:UIControlStateNormal];

    [button addTarget:self action:@selector(pushView:) forControlEvents:UIControlEventTouchUpInside]; 

    [self.view addSubview:button];

}

- (void)pushView:(UIViewController *)viewController
{             
    if([delegate respondsToSelector:@selector(pushViewController:)]) 
        [delegate pushViewController:viewController];

    NSLog(@"pushView");

}

ViewController

#import "ContentViewController.h"

@interface ViewController : UIViewController <ContentViewControllerDelegate>
{
    IBOutlet UINavigationController *navigationController;
    __weak IBOutlet UIButton *navigationButton;
}

@property (strong, nonatomic) IBOutlet UINavigationController *navigationController;
@property (strong, nonatomic) ContentViewController *contentViewController;

@end

#import "ViewController.h"
#import "BinViewController.h"
#import <QuartzCore/QuartzCore.h>

@implementation ViewController
@synthesize navigationController;
@synthesize contentViewController;

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Add the navigationController and set the frame
    self.navigationController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

    [self.view addSubview:navigationController.view];

    // Init ContentViewController to set the delegate
    contentViewController = [[ContentViewController alloc] init];
    // Set the delegate
    contentViewController.delegate = self;

}

#pragma mark - ContentViewControllerDelegate Methods

-(void)pushViewController:(UIViewController *)viewController 
{    
    // This is here just to see if this instance method work ... I haven't actually sent it a view to push 
    BinViewController *binViewController = [[BinViewController alloc] init];
    [self.navigationController pushViewController:binViewController animated:YES];
}

Edit: This image should help explain the view hierarchy and what I am doing here. enter image description here

morcutt
  • 3,739
  • 8
  • 30
  • 47
  • How are you presenting this ViewController and ContentViewController? And which is supposed to be the root view controller of the navigation controller? – Firoze Lafeer Dec 24 '11 at 07:21
  • The Root View of the navigation controller is "FirstViewController" (which I have not displayed here.) ContentViewController is displayed in a "custom" modal view that is added as a subview to "ViewController". If you need to see more of this, let me know. – morcutt Dec 24 '11 at 07:29
  • The AppDelegate has reference to that. I started with a single view template and added the Navigation Controller to the "ViewController" provided. The View Controller has a NavigationController with the root view as "FirstViewController". The "ViewController" displays "ContentViewController" (when an instance method is called) as a subview and I am attempting to push a view to ViewController (which I could to FirstViewController but I do not think that would solve my problem here) from ContentViewController. I will upload a picture to explain the view hierarchy. – morcutt Dec 24 '11 at 07:45
  • You haven't said how you push contentviewcontroller. We can see you creating a new instance of it, and assigning the delegate, but when do you actually put it on the screen? I suspect that what you are putting on the screen is a different instance, where you haven't set the delegate. – jrturton Dec 24 '11 at 08:12
  • I don't ever push it. I believe I stated I add it with a custom modal view instance I created. I add it as a subview of ViewController so it can take up the whole screen and have a transparent background. Think Flipboard iPad app "Navigation Browser" that slides out over the whole view. That view is my "ContentViewController". I am aware I could use a standard modal view set the style to uimodalpresentationcurrentcontext but that didn't work the way I wanted it to. – morcutt Dec 24 '11 at 08:19
  • The way I add "ContentViewController" to ViewController is very similar to this: http://stackoverflow.com/a/7841305/311686 – morcutt Dec 24 '11 at 08:27
  • Ok, forget I said push, and just read the rest of the comment - how do you put it on the screen? There is no reason the delegate reference would be lost. Your notification solution may work but you are probably overlooking an error in your code that may give you some other problem further down the line. – jrturton Dec 24 '11 at 09:44

1 Answers1

0

Ended up using NSNotificationcenter instead of a custom delegate. Thank you for your help.

EDIT: Changed my application to use the new iOS5 UIViewController Containment. Much better!

morcutt
  • 3,739
  • 8
  • 30
  • 47