Lily
Lily

Reputation: 387

Not entering the function -navigationController:willShowViewController:animated:

I've been struggling with this problem for some days. I've been trying to have a persistent RightBarButtonItem in several views. By researching on several blogs and web searches, it turned out that I need to set my rightBarButtonItem in the function -navigationController:willShowViewController:animated:.

My app does not show any errors but when I try to debug or use NSLog statements, it shows that the app does not enter this function at all. I have <UINavigationControllerDelegate> in the interface of my RootViewController class, but I also set my NSXMLParser parser as a delegate to itself ([parser setDelegate:self];) in another class. Can this be a problem that the navigationController delegate is not recognized or something.

- (void)navigationController:(UINavigationController *)navigationController
      willShowViewController:(UIViewController *)viewController
                    animated:(BOOL)animated
{
     //[self.navigationController.navigationItem setRightBarButtonItem:twoButtons animated:YES];
     self.navigationItem.rightBarButtonItem = twoButtons;

     NSLog(@"We are in navigationController delegate function");
}

Upvotes: 1

Views: 1354

Answers (1)

jerrylroberts
jerrylroberts

Reputation: 3454

If you want several views to have the same rightBarButtonItem, why not create a base UIViewController that all of your views inherit? Conceptually, I think this is a better solution because not only will all of the views inherit the button, they'll get the behavior as well ;) This also allows you to override methods in your base controller just in the event that one view needs to handle a click in a slightly different manner.

@interface BaseViewController : UIViewController

@property (nonatomic, retain) YourApplicationDelegate *delegate;

- (void) setupButtons;

- (void) buttonClicked:(id)sender;

@end

#import "BaseViewController.h"

@implementation BaseViewController

@synthesize delegate=_delegate;

- (void) viewDidLoad {

    [super viewDidLoad];

    self.delegate = (YourApplicationDelegate *) [[UIApplication sharedApplication] delegate];

    [self setupButtons];
}

- (void) setupButtons {
    UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave 
                                                                        target:self 
                                                                        action:@selector(buttonClicked:)];

    self.navigationItem.rightBarButtonItem = button;

    [button release];    
}

- (void) buttonClicked:(id)sender {
    NSLog(@"Click!");
}

- (void) dealloc {
    [_delegate release];
    [super dealloc];
}

@end

/* Now the rest of your view controllers look pretty clean and you don't have a lot of
   code in your delegate method.  Most problems can be solved with a layer or two of abstraction :)  */

@interface MyViewController : BaseViewController

@end

Base ViewControllers are also a good place to inject your application delegate which you'll need a lot. That's why I included it in the code block even though it wasn't part of your question. If you wanted to use a shared instance of a button or delegate the response handler out then you can easily put that code in your delegate and leverage a base view to access it easily.

Upvotes: 4

Related Questions