Take the 2-minute tour ×

I have an application that creates a tabbarcontroller from the AppDelegate. I wanted to have a button added to the nav bar but was unable to. Eventually I managed to get hold of some working code, but I don't really understand it.

The steps were:

  1. Confirm the AppDelegate to UINavigationControllerDelegate
  2. Set the rootNavigationController.delegate = self
  3. Override navigationController:willShowViewController:animated and tabBarController:didSelectViewController

I think I follow the tabBarController:didSelectViewController code, but am lost in what is happening with navigationController:willShowViewController:animated.

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
     self.tabBarController.navigationItem.title = viewController.navigationItem.title;
     self.tabBarController.navigationItem.rightBarButtonItems = viewController.navigationItem.rightBarButtonItems;
     self.tabBarController.navigationItem.leftBarButtonItems = viewController.navigationItem.leftBarButtonItems;

- (void) navigationController: (UINavigationController*) navigationController
   willShowViewController: (UIViewController*) viewController
                 animated: (BOOL) animated
      if (viewController == tabBarController)
        UIViewController* tabViewController = tabBarController.selectedViewController;
    SEL willShowSel = @selector(navigationController:willShowViewController:animated:);

      if ([tabViewController respondsToSelector: willShowSel])
        UIViewController<UINavigationControllerDelegate>* vc =
            (UIViewController<UINavigationControllerDelegate>*) tabViewController;
        [vc navigationController: navigationController willShowViewController: vc animated: animated];
share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

This code is likely dealing with problems that occur using a UITabBarController within a UINavigationController. The UITabBarController documentation states that it needs to be the root view controller (i.e. NOT within a UINavigationController) and using it in other ways can cause problems.

What the code appears to be doing is capturing the event normally passed to viewController, checking if it is a UITabBarController and if it is, then it checks whether the visible view in the UITabBarController responds to this method, and if it does then it passes the method (selector) call on to that view.

If it is possible, I'd recommend pulling the UITabBarController out from being embedded in the UINavigationController. Might take a bit of work, but will make your code compliant. (And remove need for navigationController:willShowViewController:animated:

share|improve this answer
Thanks for the advice. I would have thought it was a fairly standard design - tab bars are the top level and a nav bar with a button. –  ardochhigh Nov 9 '12 at 19:48
I think it's simpler than that: The intent appears to be to add the button to the TBC's nav bar but TBCs do not have nav bars; only the child controllers do. –  tc. Nov 9 '12 at 19:57
add comment

Your Answer


