Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UINavigationBar -pushNavigationItem never called when new controller is pushed onto UINavigationController stack

Tags:

ios

I am doing some test tonight to look at the behavior of the native UINavigationBar. I have create a simple code snippet that does the following:

- (void)pushController {
    PHViewController *ctrl2 = [[[PHViewController alloc] initWithNibName:@"PHViewController" bundle:nil] autorelease];
    ctrl2.shouldShowPrompt = YES;
    [self.viewController pushViewController:ctrl2 animated:YES];
}


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    PHViewController *ctrl = [[[PHViewController alloc] initWithNibName:@"PHViewController" bundle:nil] autorelease];
    ctrl.shouldShowPrompt = YES;
    ctrl.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Push" 
                                                                           style:UIBarButtonItemStyleDone
                                                                          target:self
                                                                          action:@selector(pushController)] autorelease];

    self.viewController = [[[PHNavigationController alloc] initWithRootViewController:ctrl] autorelease];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

Now I have subclassed the UINavigationBar of that UINavigationController (I know this is illegal, this is an educational question) and I have overrided the following methods:

- (void)setItems:(NSArray *)items animated:(BOOL)animated {
    NSLog(@"Setting Navigation Item");
    [super setItems:items animated:animated];
}

- (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated  {
    NSLog(@"Pushing Navigation Item");
    [super pushNavigationItem:item animated:animated];
}

- (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated {
    NSLog(@"Poping Navigation Item");
    return [super popNavigationItemAnimated:animated];
}

- (void)setValue:(id)value forKeyPath:(NSString *)keyPath {
    NSLog(@"Setting Value: %@ for keyPath:%@", value, keyPath);
    [super setValue:value forKeyPath:keyPath];
}

Here's my question: Why is "Poping Navigation Item" is present in console (hence the method being called) and "Pushing Navigation Item" is not?

like image 535
Pier-Olivier Thibault Avatar asked Sep 09 '11 02:09

Pier-Olivier Thibault


2 Answers

I have found the reason: It calls - (void)pushNavigationItem:(UINavigation *)item which doesn't call - (void)pushNavigationItem:animated!

Thank you anyway!

like image 115
Pier-Olivier Thibault Avatar answered Sep 20 '22 18:09

Pier-Olivier Thibault


Here's a solution for anyone that was struggling with it like I was. In a custom UINavigationController subclass that is using your custom UINavigationBar override the pushViewController method with the following code:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [super setViewControllers:[self.viewControllers arrayByAddingObject:viewController]
                     animated:animated];
}

and then in your custom UINavigationBar subclass you can customize your navigationItems like so:

- (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated
{
    // customize your navigationItem here...

    [super pushNavigationItem:item animated:animated];
} 
like image 21
Ian Hoar Avatar answered Sep 20 '22 18:09

Ian Hoar