In XCode 4.6 how do you create a brand new iOS application combining a tabbed main application with a navigation controller on one of the tabs?


Staff member
I am trying to add a navigation controller inside a tab bar controller in a brand new non-storyboard (plain old nib) style.

I found this <a href="" rel="nofollow noreferrer">demo</a> which assumes that XCode has a new project template called "Tab Bar Application". It doesn't. Now XCode 4.6 has "New Tabbed Application". Of course, Apple in their great wisdom has decided that I should not have a main window nib (.xib) and should have the tab bar controller and its pages coded for me in the app delegate instead of in a new-user-friendly NIB instantiated tab controller. I guess that's because it's more flexible that way, and you can write code to decide what tabs the user sees and what tabs they don't see. If I turn on Storyboards, then I guess I can do everything visually still.

I am deeply confused by the long and tortured history of XCode version differences, which affect the validity of existing questions on stackoverflow and demos elsewhere on the web, that reference different iOS versions, and different XCode versions, and make assumptions specific to versions of XCode and iOS that now appear to have changed, and which each rely on different choices with respect to the contents of your
Main Nib File Base Name
being set or not set.

I also find that it seems that pre-storyboard-Nibs and the complexities of combining various UIKit widgets and controllers has been a primary motivation behind the creation of storyboards.

I am working in a real non-storyboard nib-based application that appears to have been created before this change of heart at apple, and I can see that at startup a lot of unecessary views are created automatically by nib-instantiation and then deleted, in order to dynamically hide and show tabs on the tab bar controller. This appears to have been thought about a great deal at Apple, and they've changed the recommended practices implicitly by changing the way new applications are generated in XCode. I'm not questioning their wisdom, in fact I appreciate the change, but it's left me lost and confused.

Anyways, I'm just trying to put a navigation controller inside a tab in the main tab bar, and I already have an application that must have been started back when XCode used to generate a main window and generate a "Tab Bar Application" with a top level view that is a tabbed view, and the tab bar controller is nib instantiated. The demo above assumes as much.

Apple apparently famously never has provided a demo of this obvious combination of tab bar plus navigation controller. Or so I'm told. And the Apple Human Interface Guidelines apparently state (or used to state?) that it's better to put a navigation controller inside a tab bar than vice versa, and my question should be understood as wishing to comply with the HIG however possible, so I believe I'm asking about the recommended combination, not the discouraged combination.

Here's what I've tried so far:

<li>Tried to follow <a href="" rel="nofollow noreferrer">this blog post</a>, from circa 2009, which assumes things true about older versions of XCode that are no longer true.</li>
<li>Starting with a new tabbed application which XCode generated for me, <strong>with storyboards turned OFF</strong>, I have a root app delegate .m file that it generated for me that apparently creates at app-startup time, a Tab Bar Controller object completely in code, and which has no Main Window nib. The following code is entirely written by Apple, and I am wondering where (as a relatively new Cocoa developer) I'm supposed to break into this and place my new stuff, if I wanted to change one of the tabs to hav a nav bar and its associated UINavigationViewController:</li>

-- This marker helps stackoverflow's busted markdown system not be confused --

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    UIViewController *viewController1, *viewController2;
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        viewController1 = [[RPDAFirstViewController alloc] initWithNibName:@"RPDAFirstViewController_iPhone" bundle:nil];
        viewController2 = [[RPDASecondViewController alloc] initWithNibName:@"RPDASecondViewController_iPhone" bundle:nil];
    } else {
        viewController1 = [[RPDAFirstViewController alloc] initWithNibName:@"RPDAFirstViewController_iPad" bundle:nil];
        viewController2 = [[RPDASecondViewController alloc] initWithNibName:@"RPDASecondViewController_iPad" bundle:nil];
    self.tabBarController = [[UITabBarController alloc] init];
    self.tabBarController.viewControllers = @[viewController1, viewController2];
    self.window.rootViewController = self.tabBarController;
    [self.window makeKeyAndVisible];
    return YES;

It now appears that what used to be possible without writing code (according to that 2009 example on the blog I linked to) is now done purely in code. I have read about 500 pages of "Programming iOS 5", worked for a few hundred hours on my first app, and tried a lot of demo applications but I'm still a relatively unseasoned Cocoa/iOS developer, and I believe part of my confusion over all this is the "controller and view" pattern, and its rules for combining them, both in code, and in nibs, are not entirely clear to me.


<strong>Update</strong>: You can has teh codez! <a href="" rel="nofollow noreferrer">In the interest of helping out future XCode-cocoa-iOS noobs like me, I have made a complete demo app and posted it on github here.</a>

<img src=" " alt="enter image description here">