Embedding a UITabBarController in a UINavigationController with multiple tabs: A Solution for iOS Development

Embedding a UITabBarController in a UINavigationController with multiple tabs

Introduction

In iOS development, it’s common to create iPad applications that utilize the multitasking features of iOS 5. One way to implement this is by embedding a UITabBarController within a UINavigationController. In this article, we’ll explore how to embed a UITabBarController in a UINavigationController with multiple tabs, and address some common issues you may encounter.

Understanding the Problem

The problem presented is that when the “More” button is pressed, it displays two navigation bars instead of one. This occurs because the UITabBarController is embedded within a UINavigationController, which in turn displays a second navigation bar.

The Proposed Solution

To resolve this issue, we need to rethink our approach and embed a separate UINavigationController for each tab item in the UITabBarController. We’ll also need to set up the UITabBarController as the main window root view controller.

{
  <highlight language="objectivec">
    UIViewController *prevc = [[UIViewController alloc] init];
    UINavigationController *nv1 = [[UINavigationController alloc] initWithRootViewController:prevc];

    // Repeat this process for each tab item

    UITabBarController *tb = [[UITabBarController alloc] init];
    tb.viewControllers = [NSArray arrayWithObjects:nv1, nv2, nv3, nil];
  }
  </highlight>
}

Setting up the TabBarController as the Main Window Root View Controller

To embed a UITabBarController within a UINavigationController, we need to set it as the main window root view controller. We can do this by setting its delegate property to the same class that’s implementing the UITabBarControllerDelegate protocol.

{
  <highlight language="objectivec">
    MyTabController *tabController = [[MyTabController alloc] init];

    UITabBarController *tb = [[UITabBarController alloc] init];
    tb.delegate = tabController;
    tb.viewControllers = [NSArray arrayWithObjects:nv1, nv2, nv3, nil];

    // Set the tabbarcontroller as the main window root view controller
    [[UIApplication sharedApplication] setMainViewController:tb];
  }
  </highlight>
}

Resolving the Navigation Bar Issue

To resolve the issue of two navigation bars being displayed when pressing the “More” button, we need to hide the second navigation bar.

{
  <highlight language="objectivec">
    - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
    {
      if ([viewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController *nv = (UINavigationController *)viewController;
        nv.navigationBarHidden = YES;
      }
    }
  }
}

Example Code

Here’s an example code snippet that demonstrates how to embed a UITabBarController in a UINavigationController with multiple tabs.

{
  <highlight language="objectivec">
    UIViewController *prevc = [[UIViewController alloc] init];

    UINavigationController *nv1 = [[UINavigationController alloc] initWithRootViewController:prevc];
    UINavigationController *nv2 = [[UINavigationController alloc] initWithRootViewController:[UIViewController new]];
    UINavigationController *nv3 = [[UINavigationController alloc] initWithRootViewController:[UIViewController new]];

    UIViewController *vc1 = [[UIViewController alloc] init];
    vc1.hidesBottomBarWhenPushed = YES;

    UITabBarController *tb = [[UITabBarController alloc] init];
    tb.viewControllers = [NSArray arrayWithObjects:nv1, nv2, nv3, nil];

    // Set the delegate property to the same class that's implementing the UITabBarControllerDelegate protocol
    tb.delegate = self;

    // Set the tabbarcontroller as the main window root view controller
    [[UIApplication sharedApplication] setMainViewController:tb];
  }
}

Conclusion

In this article, we explored how to embed a UITabBarController in a UINavigationController with multiple tabs. We also addressed some common issues that may arise when implementing this design pattern.

To resolve the issue of two navigation bars being displayed when pressing the “More” button, we need to hide the second navigation bar by setting its hidden property to YES.


Last modified on 2024-02-04