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){ // 加载,涉及到该项目的视图控制器,并释放其他 } ...等
}
不知道为什么你会想要做到这一点,如果涉及内存问题,当前选项卡将无论如何都会被卸载。这就是--viewWillAppear,-viewDidUnload等等。
我可以回答在一两个问题...
你只需要充当的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];
}
现在我的代码只是使标签栏淡入淡出,但您也可以在这里工作来卸载未使用的标签页。如果某些选项卡使用大量内存,有时候这是个好主意。
谢谢我可能会使用如果我决定让过渡动画。 – mk12 2009-08-14 04:18:43
UITabBarController延迟加载其所有视图控制器。当一个标签被切换出来时,它的视图可能会在内存紧张的情况下被释放。当它被第二次选择时,它被重新创建。此外,大部分内存命中都在视图中,而不是视图控制器。因此,不要担心视图控制器的内存命中。这个观点就是这个过程。
如果您正在操作系统的v3上运行,那么您可以使用-viewDidUnload方法来确保减少内存的最大量。
Andrew
延迟加载不是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];
}}
这是一种糟糕的编码风格,它使用当前实现方法的副作用来实现目标。 didReceiveMemoryWarning的实现可能会改变并破坏您对其行为的假设。由于行为不明确,这也很难调试。 – ikuramedia 2012-01-31 07:26:32
我没有说我知道如何重新创建uitabbarcontroller,这是我必须要做的事来管理我自己的标签栏。也许我可以尝试.. – mk12 2009-08-13 19:23:13
它不难,你只需要实现一个方法做了selectItem,然后你做你的设置取决于选择的项目,非常直接,你可以做这种方式的延迟加载 – Daniel 2009-08-13 19:35:10
那么你说我应该让我自己的uiviewcontroller类懒加载和使用标签栏或使用UITabBarController?我尝试了didSelectItem方法,我无法让它正常工作。 – mk12 2009-08-13 23:42:02