I have a UITabBarController created programaticaly that manages 4 subclasses of UIViewController. Something like:
//Create Controller 1
self.terminal = [[[TerminalController alloc] initWithNibName:@"TerminalView" bundle:nil] autorelease];
UINavigationController* navTerminal = [[[UINavigationController alloc] initWithRootViewController:terminal] autorelease];
navTerminal.title = __(@"Terminal");
navTerminal.navigationBar.barStyle = UIBarStyleBlackOpaque;
navTerminal.tabBarItem.image = [UIImage imageNamed:@"tab_terminal.png"];
//Create Controller 2
self.history = [[[HistoryController alloc] initWithNibName:@"HistoryView" bundle:nil] autorelease];
UINavigationController* navHistory = [[[UINavigationController alloc] initWithRootViewController:history] autorelease];
navHistory.title = __(@"History");
navHistory.navigationBar.barStyle = UIBarStyleBlackOpaque;
navHistory.tabBarItem.image = [UIImage imageNamed:@"tab_history.png"];
//Create Controller 3
self.settings = [[[SettingsController alloc] initWithNibName:@"SettingsView" bundle:nil] autorelease];
UINavigationController* navSettings = [[[UINavigationController alloc] initWithRootViewController:settings] autorelease];
navSettings.title = __(@"Settings");
navSettings.navigationBar.barStyle = UIBarStyleBlackOpaque;
navSettings.tabBarItem.image = [UIImage imageNamed:@"tab_settings.png"];
//Create Controller 4
HelpController* help = [[[HelpController alloc] initWithNibName:@"HelpView" bundle:nil] autorelease];
UINavigationController* navHelp = [[[UINavigationController alloc] initWithRootViewController:help] autorelease];
navHelp.title = __(@"Help");
navHelp.navigationBar.barStyle = UIBarStyleBlackOpaque;
navHelp.tabBarItem.image = [UIImage imageNamed:@"tab_help.png"];
//Create Tab Bar an add it's view to window.
self.tabBar = [[[UITabBarController alloc] initWithNibName:nil bundle:nil] autorelease];
tabBar.viewControllers = [[[NSArray alloc] initWithObjects:navTerminal, navHistory, navSettings, navHelp, nil] autorelease];
tabBar.delegate = self;
[window addSubview:tabBar.view];
Is there a way to tell the UITabBarController to load the view controllers lazily? ej, when the user clicks one of the tab bar items or when tabBarController setSelectedIndex is called?
I'm doing this very thing in one of my apps. The trick is to make your view controller NOT be a subclass of UITabBarController, but rather UIViewController, and implement UITabBarDelegate. I created the view for this in IB, laying out the tab bar (with the proper # of buttons, images, tags, etc.) and a placeholder UIView which is used to properly place the subviews that are swapped in and out. View switching happens on tabBar:didSelectItem: It looks something like this:
The code could surely be made more DRY, but you get the idea.
What are you trying to load lazily?
This is a pretty standard UITabBarController implementation. I have one very similar to it in an application I am writing. In my code the viewDidLoad (the method called after a controller has loaded its associated views into memory) is not called until the tab is touched.
I do believe the way you have coded (aside from all of the autoreleased objects) is the preferred method of creating this kind of UI.
A UITabBarController requires that actual view controllers be set for its
viewControllers
property - there's no lazy loading available from Apple's frameworks. The tab bar controller relies on certain aspects of the controllers it loads for its properties. However, it doesn't callviewDidLoad
until the tab is pressed for the first time.What you can do instead is create your own "placeholder" view controller that, in its
viewDidLoad
orviewWillAppear
methods, replaces itself in the tab bar controller with its actual view controller. That way, you can minimize the memory used by the view controllers held by the tab bar controller until you load a certain tab's view controller and replace it with your more memory- and processor-intensive controller.Side note: You'll want to change the tab bar controller's
viewControllers
property directly, rather than use thesetViewControllers:animated:
method, so that your users don't see an animation every time you load a new controller.You can always not use a UITabBarController and manage the tabbar urself, when someone selects a tab u push the viewcontrollers view in in the didSelectIndex method
Within the custom UITabBarController's didSelectItem method, you should simply just make this call: