iPhone Dev - 懒加载一个标签栏应用程序

问题描述:

我怎么能这样做,当选项卡被选中,当前的一个被卸载,并且下一个被加载,所以一次只加载一个?或者我应该不这样做?我知道如何使用普通的UIViewController作为根VC,但不确定使用UITabBarController。另外,有没有办法让一个标签到另一个标签的过渡动画?任何帮助?谢谢!!iPhone Dev - 懒加载一个标签栏应用程序

编辑:...如果我卸载视图控制器,那么他们的标签栏上的图标都不见了...也许我就卸下了自己的看法..

你不能真正管理的UITabBarController unfortunaly所以你不能做懒加载。你可以通过管理你自己的TabBar,但你说你已经知道,

来管理你自己的标签栏,尽管你要做的就是在ViewController中设置一个带有TabBarItems的UITabBar,然后实现TabBar委托协议,主要是 - 的TabBar:didSelectItem:方法基础上,项目编号,你可以加载新的视图控制器和释放任何其他 所以每当tabbarItem选择改变其被调用,那么:编辑:这一代码进入在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 *)ite米 { 如果(item.tag == 0){ // 加载,涉及到该项目的视图控制器,并释放其他 } ...等

} 
+0

我没有说我知道如何重新创建uitabbarcontroller,这是我必须要做的事来管理我自己的标签栏。也许我可以尝试.. – mk12 2009-08-13 19:23:13

+1

它不难,你只需要实现一个方法做了selectItem,然后你做你的设置取决于选择的项目,非常直接,你可以做这种方式的延迟加载 – Daniel 2009-08-13 19:35:10

+0

那么你说我应该让我自己的uiviewcontroller类懒加载和使用标签栏或使用UITabBarController?我尝试了didSelectItem方法,我无法让它正常工作。 – mk12 2009-08-13 23:42:02

不知道为什么你会想要做到这一点,如果涉及内存问题,当前选项卡将无论如何都会被卸载。这就是--viewWillAppear,-viewDidUnload等等。

+0

我知道,但我认为它最好在没有看到的时候卸载任何你没有使用的东西,并且不要将它推到内存警告。 – mk12 2009-08-13 19:24:24

+0

就像我有两个视图,按下按钮切换它们,然后加载下一个,删除旧的,加入新的,卸载旧的。 – mk12 2009-08-13 19:25:20

+0

如果它达到了内存警告的地步,会有其他一些事情发生,比如删除缓存的Safari浏览器页面等,这些会对应用程序产生显着影响。 – mk12 2009-08-14 04:16:32

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

你只需要充当的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]; 
} 

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

+0

谢谢我可能会使用如果我决定让过渡动画。 – mk12 2009-08-14 04:18:43

UITabBarController延迟加载其所有视图控制器。当一个标签被切换出来时,它的视图可能会在内存紧张的情况下被释放。当它被第二次选择时,它被重新创建。此外,大部分内存命中都在视图中,而不是视图控制器。因此,不要担心视图控制器的内存命中。这个观点就是这个过程。

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

Andrew

+0

是的,我知道它在“内存紧张的情况下”,但我更喜欢一次只分配一个视图,或者一个视图控制器。我决定使用我自己的UIViewController子控件(使用UITabBar)作为根视图控制器,而不是UITabBarController的实例,因为这样我就可以控制所有事情,并且知道发生了什么并且更有效地延迟加载。 – mk12 2009-08-14 04:13:58

+0

解除分配视图控制器也会释放它的视图。 – mk12 2009-08-14 06:33:24

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

要释放与每个UIViewControllers关联的UIView,每次更改TabBarItem时,必须在与您的UITabBarController关联的每个UIViewController子类中实现以下方法。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]; 
} 

这意味着内容查看他们的记忆responsabilities内的每个对象都要求在内容查看,被释放并连接到self.view属性。

在这种情况下,除去self.view(即对contentView的引用),导致每个对象的多米诺骨牌式释放,那就是您的目标。

问候

我目前使用这个卸载标签栏不活动的视图控制器

(根据Kendall的答案)

- (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]; 

}}

+0

这是一种糟糕的编码风格,它使用当前实现方法的副作用来实现目标。 didReceiveMemoryWarning的实现可能会改变并破坏您对其行为的假设。由于行为不明确,这也很难调试。 – ikuramedia 2012-01-31 07:26:32