Search
davedelong's tweets
- @JayCarr it's in the prefs, under "Advanced" — 11 hours 22 min ago
- so that bug i was tracking down all afternoon wasn't actually my bug. silly xib using a wonky encoding :P — 14 hours 46 min ago
- @alesplin 5 pm Mountain Time, i think — 16 hours 49 min ago
- @JayCarr not yet... — 17 hours 19 min ago
- Software Engineering is the "[art of making] software accessible to those who do not know how it works." http://bit.ly/9cNqsF — 23 hours 22 min ago
- 1 of 477
- ››
Adding UINavigation/UITableView controllers into a UITabBarController
davedelong — Wed, 05/13/2009 - 08:13
I don't get why this is a big question, but I've seen it come up about 5 times in the past week, so I thought I'd offer my insights on the topic.
Before beginning, however, I will put out my one caveat that is probably the source of almost all the frustration I've been reading about: For something like this, it is vitally important that you DO NOT use Interface Builder.
Don't get me wrong; Interface Builder is a fantastic application, but I think it's pretty ineffective when it comes to dealing with embedding UIViewControllers in UIViewControllers.
So, here's how you embed UINavigationControllers in a UITabBarController:
- Understand, first of all, that all a UITabBarController does is manage an array of UIViewControllers
- Understand that UITabBarController, UINavigationController, UITableViewController, etc are all subclasses of UIViewController
- In the object that's going to control the UITabBarController itself, declare the UITabBarController as an instance variable for that class. For me, this is typically my AppDelegate object, and looks something like this:
@interface AppDelegate : NSObject <UIApplicationDelegate> { UITabBarController * tabBarController; //.... other instance variables } //... method declarations @end
- In the appropriate method (and going with the assumption that this is your AppDelegate, then the appropriate method is most likely
applicationDidFinishLaunching:), create all of the view controllers that you want to be in your tab bar:
#import "FirstNavigationHierarchyController.h"; #import "SecondNavigationHierarchyController.h"; #import "MyTableViewController.h" @interface AppDelegate - (void) applicationDidFinishLaunching:(NSNotification *)aNotification { FirstNavigationHierarchyController * first = [[FirstNavigationHierarchyController alloc] init]; SecondNavigationHierarchyController * second = [[SecondNavigationHierarchyController alloc] init]; MyTableViewController * table = [[MyTableViewController alloc] init]; //we'll deal with these in a second } @end
- Remember, a UITabBarController manages an ARRAY of UIViewControllers, so let's make an array:
- Now, we create the UITabBarController:
//... instantiation of the tabs array tabBarController = [[UITabBarController alloc] init];
- Tell the UITabBarController which UIViewControllers it's going to manage:
//... instantiation of the tabBarController [tabBarController setViewControllers:tabs];
- Since the "tabs" array has retained the first, second, and table View Controllers, and since tabs has been retained by tabBarController, we can release them so we don't leak memory:
[first release]; [second release]; [table release]; [tabs release];
- Finally, we have to actually put our UITabBarController on the window (again, assuming that this is your AppDelegate object):
//... releasing the array and view controllers [window addSubview:[tabBarController view]];
- And don't forget to release the UITabBarController in your -dealloc method:
- (void) dealloc { [tabBarController release]; //other releases [super dealloc]; }
- Enjoy.
So your entire -applicationDidFinishLaunching: method looks like this:
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification { FirstNavigationHierarchyController * first = [[FirstNavigationHierarchyController alloc] init]; SecondNavigationHierarchyController * second = [[SecondNavigationHierarchyController alloc] init]; MyTableViewController * table = [[MyTableViewController alloc] init]; NSArray * tabs = [[NSArray alloc] initWithObjects:first, second, table, nil]; tabBarController = [[UITabBarController alloc] init]; [tabBarController setViewControllers:tabs]; [first release]; [second release]; [table release]; [tabs release]; [window addSubview:[tabBarController view]]; }
There. Wasn't that easy?
As a point of clarification, FirstNavigationHierarchyController and SecondNavigationHierarchyController are both subclasses of UINavigationController. However, for the same effect, you don't need to subclass UINavigationController. You can instead use them like this:
//Both First- and SecondNavigationHierarchyRoot are UIViewController subclasses FirstNavigationHierarchyRoot * root1 = [[FirstNavigationHierarchyRoot alloc] init]; SecondNavigationHierarchyRoot * root2 = [[SecondNavigationHierarchyRoot alloc] init]; UINavigationController * first = [[UINavigationController alloc] initWithRootViewController:root1]; UINavigationController * second = [[UINavigationController alloc] initWithRootViewController:root2]; [root1 release]; [root2 release];
I use this method every time I need a UITabBarController or UINavigationController, regardless of what they're going to contain. I've tried doing this same process in Interface Builder and have always ended up tearing my hair out. In my opinion, it is supremely easier to set these sorts of things up through code.
Dave
Update 15 June 2009
For a class I'm taking at school, we had to write an instruction manual detailing a technical process. I decided to write about this very topic, and the resulting PDF is available for free in the Downloads section.

Interface Builder
cmkilger — Sat, 05/23/2009 - 21:36I just need to say that I think it's easier in IB. I can do it in about 15 seconds.
IB in seconds
Anonymous — Mon, 06/15/2009 - 19:14takes me 20 seconds in IB
Yeah, I never got the hang of
davedelong — Mon, 06/15/2009 - 19:17Yeah, I never got the hang of dealing with view controllers in IB. Doing it through code makes a heck of a lot more sense to me.
How I can add TabBarItem with
Anonymous — Thu, 05/28/2009 - 00:41How I can add TabBarItem with icon to my TabBarController for each view ?
Thanks
Thanks
Anonymous — Tue, 06/23/2009 - 14:47Much easier than interface builder for me.
Nice tutorial
Anonymous — Mon, 08/24/2009 - 08:22I can do it both ways, in about 15 minutes, not sure how u guys do it in 15 seconds.. that's crazy fast