iPhone Dev - 延迟加载选项卡栏应用程序

发布于 2024-07-30 13:12:55 字数 246 浏览 5 评论 0原文

如何才能做到当选择一个选项卡时,卸载当前选项卡,并加载下一个选项卡,以便一次只加载一个选项卡? 或者我什至不应该这样做? 我知道如何使用普通的 UIViewController 作为根 VC,但不确定如何使用 UITabBarController。 另外,有没有一种方法可以动画化从一个选项卡到下一个选项卡的过渡? 有什么帮助吗? 谢谢!!

编辑:...如果我卸载视图控制器,那么选项卡栏上的图标就会消失...也许我只会卸载它们的视图..

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..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

等风来 2024-08-06 13:12:55

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

您只需要一个充当 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];  
}

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

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.

旧伤还要旧人安 2024-08-06 13:12:55

不幸的是,您无法真正管理 UITabBarController,因此您无法进行延迟加载。 你可以通过管理你自己的TabBar,但你说过你已经知道了,

要管理你自己的标签栏,尽管你所要做的就是在ViewController中设置一个带有TabBarItems的UITabBar,然后实现TabBar Delegate协议,主要是 – tabBar:didSelectItem :每当 tabbarItem 选择发生更改时都会调用该方法,然后根据项目 id,您可以加载新的 ViewController 并释放任何其他 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并释放其他ViewController
}
...ETC

}

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

}
寄风 2024-08-06 13:12:55

延迟加载不是 UITabBarController 任务。 相反,它是与选项卡关联的视图控制器的责任。

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

-(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 的引用)导致每个对象的多米诺骨牌式释放,这就是您的目标。

此致

Lazy loading is not an UITabBarController task. Instead, it is responsability of your viewControllers associated with your Tab.

To release the UIView, associated with each UIViewControllers, every time you change the TabBarItem, you must implement the following method in each UIViewController subclass, associated with your UITabBarController.viewControllers property:

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

Obviously, this will remove the self.view associated with your UIViewController. However, if your code is smart enough, this will remove all the related objects.
For example, suppose that your loadView method is as follow:

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

This means that every object inside the contentView and their memory responsabilities are demanded to the contentView, that is released and attached to the self.view property.

In this scenario, removing the self.view (that's the reference to the contentView) resulting in a domino-style releasing of every object, that's your goal.

Best regards

桃气十足 2024-08-06 13:12:55

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

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.

空城之時有危險 2024-08-06 13:12:55

UITabBarController 会延迟加载其所有视图控制器。 当选项卡被切换出时,它的视图可能会在内存紧张的情况下被释放。 当第二次选择它时,它会被重新创建。 此外,大部分内存命中都在您的视图中,而不是视图控制器中。 因此,不必担心视图控制器对内存的影响。 观点就是成果。

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

安德鲁

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

眼波传意 2024-08-06 13:12:55

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

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

}
}

I'm currently using this to unload inactive view controllers in the tab bar (based on Kendall's answer)

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

}
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文