views:

2274

answers:

4

How can I make it so when a tab is selected, the current one is unloaded, and the next one is loaded so only one loaded at a time? Or should I not even do this? I know how to do it with a normal UIViewController as the root VC, but not sure with a UITabBarController. Also, is there a way to animate the transition from one tab to the next? Any help? Thanks!!

EDIT: ... If I unload the view controllers, then their icons on the tab bar are gone... maybe I'll just unload their views..

+1  A: 

You cant really manage the UITabBarController unfortunaly so you cant do lazy loading. You can by managining your own TabBar but you said u knew that already,

to manage your own tab bar though all you gotta do is setup a UITabBar with its TabBarItems in a ViewController, then implement the TabBar Delegate protocol, mainly the – tabBar:didSelectItem: method which is called whenever the tabbarItem selection is changed, then based on the item id you can load your new ViewController and release any others so: Edit: this code goes in your UIViewController

  -(void)addTabBar{
    NSMutableArray* items=[[NSMutableArray alloc] init];
    UITabBarItem *eventsItem= [[UITabBarItem alloc] initWithTitle:@"Events" image:nil   tag:0];
    UITabBarItem *albumItems=[[UITabBarItem alloc] initWithTitle:@"Album" image:nil tag:1]; //the tag is how you tell what was clicked
    [items addObject:homeItem];
    [items addObject:albumItems];
      //MyTabBar is of type UITabBar
    myTabBar=[[UITabBar alloc] initWithFrame:CGRectMake(0,411,320,49)];
    [myTabBar setItems:items];
    myTabBar.delegate=self; //you gotta implement the UITabBar delegate protocol
    [myTabBar setSelectedItem:eventItem]; //set the selected item
    [homeItem release];
    [eventsItem release];
    [albumItems release];
    [items release];
   [self.view addSubview:myTabBar]
}

then the protocol method would look something like below - (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item { if(item.tag == 0 ) { //load the ViewController that pertains to this item and release others } ...etc

}
Daniel
I didn't say I knew how to recreate uitabbarcontroller though, which is what I'd have to do to manage my own tab bar. Maybe I could try..
Mk12
its not hard at all, you just need to implement one method did selectItem, and then you do your setup depending o n the item selected, very straight forward and you can do lazy loading that way
Daniel
So are you saying I should make my own uiviewcontroller class that lazy loads and uses a tab bar or use UITabBarController? I tried the didSelectItem method, I couldn't get it to work right.
Mk12
you have to use a UITabBar not a UITabBarController and implement the UITabBar delegate protocol check out my edit
Daniel
Ok thanks I get it.
Mk12
A: 

Not sure why you'd want to do this, the current tab will get unloaded anyway if there's a memory issue involved. That's what -viewWillAppear, -viewDidUnload, etc. are for.

Jordan
I know, but I thought its better to unload anything that you're not using as soon as it isn't seen, and not push it to a memory warning.
Mk12
Like if I have two views, pressed a button to switch them, then load the next, remove the old one, add in the new one, unload the old one.
Mk12
If it gets to the point of a memory warning, there will be other things going on like deleting cached safari pages etc. that will have a noticeable effect on the app.
Mk12
Two reasons to lazy-load the view controllers in the tabs: To reduce startup time and to better manage memory.
Jason Moore
+3  A: 

I can answer both questions in one...

You just need a class that acts as the UITabBarController delegate, then implement a method like so:

// Animate tab selections so they fade in and fade out
-(void)tabBarController:(UITabBarController*)tbc didSelectViewController:(UIViewController*)newSelection
{
    [UIView beginAnimations:@"TabFadeIn" context:nil];
    [UIView setAnimationDuration:0.6];
    for( UIViewController* vc in tbc.viewControllers )
        vc.view.alpha = (vc==newSelection) ? 1 : 0;
    [UIView commitAnimations];  
}

Now my code simply makes the tab bars fade in and out, but you could also do work here to unload non-used tabs. Sometimes that is a good idea if some of the tabs will be using a ton of memory.

Kendall Helmstetter Gelner
Thanks I might use that If I decide to animate the transition.
Mk12
A: 

UITabBarController does lazy load all of its view controllers. When a tab is switched out, then it's view is subject to being deallocated in a memory tight situation. It is then recreated when it is chosen the second time. Furthermore, most of your memory hits are in your views and not the view controllers. Hence, don't worry about the memory hit from the view controller. The view is the proze.

If you are running on v3 of the OS, then you can use the -viewDidUnload method to ensure the maximal amount of memory reduction.

Andrew

adonoho
Yes, I know it does in "memory tight situation", But I prefer to only have one view allocated at a time, or one view controller. I decided to use my own UIViewController subclas (with a UITabBar in it) as the root view controller instead of an instance of UITabBarController because this way I can control everything and know what's going on and lazy-load more efficiently.
Mk12
And deallocating a view controller also deallocates it view.
Mk12