matrix4use
matrix4use

Reputation: 631

Navigation Bar not accessible from Tab Bar controller

Shown in the image below is a setup that I'm trying to create with the following hierarchy:

  1. Root Single View Controller (from left, second view in screenshot) embedded into a Navigation Controller (from left, first view in screenshot).
  2. Tab Bar Controller (from left, third view in screenshot that is accessed from the root vc
  3. 2 View Controllers (the 2 most right views in screenshot) that are embedded in the tab bar controller and seemingly also still in the navigation bar controller.

Each Tab Bar Controller shows a navigation bar (as you can see in the right 2 views). The logic that does work is that when I press the button on the root, the tab bar controller opens. You can navigate between tabs via the tab bar and you get back to the root by pressing the back button in the navigation bar.

What I don't understand is how I can access the navigation bar on each of the right most views. As mentioned above, the navigation bar shows the back button, but I can't access the title, or add any navigation bar buttons. When I do, nothing is displayed (except for the back button). So What I want is to be able to set the title of the navigation bar in each view controller that is connected to the tab bar controller. And as shown in the screenshot below, there clearly is a navigation bar which comes from embedded root view controller.

Some more info that may make things clearer:

Any Ideas What I'm Doing Wrong ?? Thanks!

tab/navigation controllers

Upvotes: 0

Views: 4491

Answers (2)

Larry Borsato
Larry Borsato

Reputation: 394

In your viewDidLoad method in each view controller you should do this (changing the title from @"Contacts" as appropriate:

self.title = @"Contacts";
self.navigationItem.rightBarButtonItem = nil; // if no button is used

The view controller is responsible for its own navigation bar. In your AppDelegate you can create the tab bar controller like this:

// Create a tabbar controller and an array to contain the view controllers
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.delegate = self;

NSMutableArray *localViewControllersArray   = [[NSMutableArray alloc] init];

//  Setup first view and nav controllers
UIViewController *vc1 = [[UIViewController alloc] init];
UINavigationController *nc1 = [[UINavigationController alloc] initWithRootViewController:vc1];
[localViewControllersArray addObject:nc1];

//  Setup second view and nav controllers
UIViewController *vc2 = [[UIViewController alloc] init];
UINavigationController *nc2 = [[UINavigationController alloc] initWithRootViewController:vc2];
[localViewControllersArray addObject:nc2];

// set the tab bar controller view controller array to the localViewControllersArray
tabBarController.viewControllers = localViewControllersArray;

[self.window setRootViewController:tabBarController];

Upvotes: 0

matrix4use
matrix4use

Reputation: 631

I found a way to do it:

In each view controller managed by the tab bar controller, I add this to the viewWillAppear method:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    PHOrderTabBarViewController *orderTabBarViewController = (PHOrderTabBarViewController *)self.tabBarController;
    orderTabBarViewController.title = @"Contacts";
    orderTabBarViewController.navigationItem.rightBarButtonItem = nil; // if no button is used
}

PHOrderTabBarViewController is the TabBarViewController that manages the view controllers on the right side of the screenshot. Since the navigation controller is embedded in the TabBarViewController, I have to set the title and any buttons from there.

Note!!: When navigating between tabs, the above needs to be added to each view controller managed by the tab bar controller. Otherwise, the navigation bar items will carry over to the other views. (E.g. in my code, the navigation title is set to 'Contacts', if I would press on the other tab, it would still display 'Contacts' unless I reset the title/button in that view's viewWillAppear method.

With this result, I'm not sure if this is the right behavior or pattern to use here. The app now works as expected, but I don't know if I will run into issues with navigation if any of the tabbed bar controllers need to navigate into deeper hierarchies. Also, I haven't tried what @AmroShafie has suggested, but if I do, I will come back to note the outcome.

Upvotes: 3

Related Questions