iPhone开发 - 懒惰加载标签栏应用程序

时间:2009-08-13 18:58:01

标签: iphone uiviewcontroller uitabbarcontroller lazy-loading

当选择一个标签时,如何卸载当前标签,然后加载下一个标签,以便一次只加载一个标签?或者我不应该这样做?我知道如何使用普通的UIViewController作为根VC,但不确定使用UITabBarController。此外,有没有办法动画从一个标签到下一个标签的过渡?有帮助吗?谢谢!

编辑:...如果我卸载视图控制器,那么它们在标签栏上的图标就不见了......也许我只是卸载他们的视图..

6 个答案:

答案 0 :(得分:3)

我可以一个回答这两个问题......

您只需要一个充当UITabBarController委托的类,然后实现如下方法:

// 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];  
}

现在我的代码只是让标签栏淡入淡出,但你也可以在这里卸载未使用的标签。如果某些选项卡使用大量内存,有时候这是个好主意。

答案 1 :(得分:1)

你真的不能真正管理UITabBarController所以你不能进行延迟加载。你可以通过管理你自己的TabBar,但你说你已经知道了,

管理你自己的标签栏虽然你要做的就是在ViewController中设置一个带有TabBarItems的UITabBar,然后实现TabBar Delegate协议,主要是 - tabBar:didSelectItem:只要tabbarItem选择被更改,就调用它,然后根据项目ID,您可以加载新的ViewController并释放任何其他 所以:编辑:这段代码放在你的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]
}

然后协议方法看起来如下所示      - (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item     {          if(item.tag == 0)          {            //加载与此项相关的ViewController并释放其他项          }          ...等

}

答案 2 :(得分:1)

延迟加载不是UITabBarController任务。相反,它是与您的Tab相关联的viewControllers的责任。

要释放与每个UIViewControllers关联的UIView,每次更改TabBarItem时,必须在每个UIViewController子类中实现以下方法,与UITabBarController.viewControllers属性相关联:

-(void)viewDidDisappear {
[self.view removeFromSuperview];
self.view = nil;
}

显然,这将删除与您的UIViewController相关联的self.view。但是,如果您的代码足够智能,则会删除所有相关对象。 例如,假设您的loadView方法如下:

-(void)loadView {
UIView *contentVew = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.view = contentView;
…
...
UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,320,50)];
…
…
[contentView addSubview:aLabel];
[aLabel release];
…

[contentView release];
}

这意味着contentView中的每个对象及其内存响应都需要contentView,它将被释放并附加到self.view属性。

在这种情况下,删除self.view(这是对contentView的引用)导致每个对象的多米诺式释放,这是你的目标。

祝你好运

答案 3 :(得分:-1)

不确定为什么要这样做,如果涉及内存问题,当前选项卡无论如何都会被卸载。这就是-viewWillAppear,-viewDidUnload等等。

答案 4 :(得分:-1)

UITabBarController延迟加载其所有视图控制器。当切换选项卡时,它的视图可能会在内存紧张的情况下被释放。然后在第二次选择时重新创建它。此外,大多数内存命中都在视图中,而不是视图控制器。因此,不要担心视图控制器的内存命中。观点是一种观点。

如果您在操作系统的v3上运行,那么您可以使用-viewDidUnload方法来确保最大的内存减少量。

安德鲁

答案 5 :(得分:-1)

我正在使用它在标签栏中卸载非活动视图控制器(基于肯德尔的回答)

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:  (UIViewController *)viewController {
    // reload all inactive view controllers in the tab bar
 for (UIViewController *vc in tabBarController.viewControllers) {
  if(vc != viewController)
   [vc didReceiveMemoryWarning];

}  }