【问题标题】:How to optimize performance in view controller navigation with UISegmentedControl and UITabBarController如何使用 UISegmentedControl 和 UITabBarController 优化视图控制器导航的性能
【发布时间】:2011-07-27 16:33:33
【问题描述】:

在我正在进行的一个项目中,设计决定是在顶部使用 UISegmentControl,在底部使用 UITabBarController。 UISegmentControl 为 3 个不同的视图提供 3 个选项。目前,我的同事将所有3个视图添加到NSArray,然后选择该特定选项卡,然后基于UiseGendControl,所选的视图获取到求,其他两个是隐藏的。它似乎没有遵循 Apple 的延迟加载指南,而且似乎很昂贵,因为 3 个 viewDidLoads(对数据库进行查询)一次全部加载。第一次选择选项卡时会出现一些延迟,一次加载所有 3 个视图控制器。

有没有更好的方法来做到这一点?我看到了一个简单的例子,它只有两个 viewController,以及一个可以在两个视图之间切换的按钮。这对我来说很有意义,因为你总是知道你以前的视图是什么,你可以从超级视图中删除那个视图,展示你的新视图,释放你的旧视图。但是有 3 个选择,我不知道如何跟踪我的视图层次结构(因为我可能在段 0 上,显示视图 0,然后转到段 2,显示视图 2)。我不确定如何检查显示的最后一个视图,即使这是最好的方法。我在想,如果有更好的选择来跟踪这一点,但仍然使用段控制,那么最好在项目变得更复杂之前现在就这样做。谢谢!

【问题讨论】:

  • 你有 3 个不同的视图——它们都连接到同一个视图控制器?
  • 我猜是的,因为在第一段的末尾你提到了 3 个 VC。
  • 是的,有 3 个不同的视图控制器,每个控制器都有自己的视图。他在主视图控制器上使用了一组视图控制器,在 viewDidLoad 中初始化了所有 3 个,然后根据段控制一次只显示一个,隐藏其他的。
  • 是的,这不是一个好方法,IMO。除了您已经注意到的延迟之外,还有两个 VC 被加载到内存中的内存消耗问题。这些 VC 可能永远不会显示,因此将它们保存在内存中并不是一个好主意。

标签: iphone objective-c cocoa-touch uiviewcontroller


【解决方案1】:

我建议创建一个根视图控制器,其工作是管理段控件并根据选择的段控件中的哪个按钮加载正确的 VC。根 VC 的视图将有一个 subView,其中插入了分段控件的 VC 视图。比如:

- (void)segmentAction:(id)sender
{
    NSParameterAssert([sender isKindOfClass: [UISegmentedControl class]]);
    switch ([sender selectedSegmentIndex]) {
        case 0:
            MYViewController1 *vc = [[MyViewController1 alloc] init];
            self.segmentVC = vc;
            self.segmentSubvew = vc.view;
            [vc release];
            break;
    }
}

人们倾向于挂断的一件事是,每屏内容只需要 1 个 VC - 虽然这是 Apple 最初的建议,但后来他们改变了这个建议。因此,在 SegmentManagerVC 中加载特定于细分市场的 VC 是完全可以接受的。

您可以进一步调整此设计以提高性能。例如,您可以最初为默认选定的段加载 VC,然后延迟加载其他两个,以便在选择不同的段时它们已经可用。但是,如果您采用这种方法,请务必连接-didReceiveMemoryWarning 以释放当前未查看的两个 VC。

【讨论】:

    【解决方案2】:

    您可以将视图推送/弹出到 UINavigationControler 堆栈。如果您愿意,这也将支持“后退”按钮。

        [self.navigationController pushViewController:self.myVC animated:YES];
    

    将一个方法链接到 SegmentedControl,该方法在选择相应的段时推送适当的 ViewController。内部带有分段控件的 VC 需要对每个分段的相应 VC 的引用。 viewDidLoad() 只会被调用一次,并且只会在视图第一次被推送到导航堆栈时被调用。

    当你改变视图或想要“返回”时,你可以将 VC 从堆栈中弹出:

    [self.navigationController popViewControllerAnimated:YES];
    

    这是您正在寻找的功能类型吗?


    为清晰而编辑

    UIViewController 参考:

    每个视图都需要对其他两个视图的 ViewController 的引用。这可以这样完成:(假设我们在“View1”,我们也有“View2”和“View3”:

        View2Controller v2Controller = [[View2Controller alloc] initWithNibName:@"View2" bundle:nil];
        View3Controller v2Controller = [[View3Controller alloc] initWithNibName:@"View3" bundle:nil];
    

    self.navigationController 的引用应在您应用的委托中声明为:

    UINavigationController* navigationController;
    

    可以初始化为:

    [navigationController initWithRootViewController: rootViewController];
    

    RootViewController

    rootViewController 是对应于应用程序根视图的 UIViewController(无论启动时加载什么)。它在委托中声明为:

    RootViewController* rootViewController;
    

    并初始化为:

        rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-10
      相关资源
      最近更新 更多