【问题标题】:UISplitViewController state restoration in iOS 8iOS 8 中的 UISplitViewController 状态恢复
【发布时间】:2014-11-09 03:23:36
【问题描述】:

在 iOS 8 上,UISplitViewController 似乎可以保存和恢复其子视图的状态,例如,主视图是否隐藏。

这是不可取的,因为我的应用程序应始终以横向显示主视图并始终以纵向隐藏它。如果用户以横向关闭应用(保存横向状态)并以纵向重新打开应用(恢复横向状态),则 UISplitViewController 会以错误的配置显示主视图。

我仍然需要为 UISplitViewController 提供恢复标识符,以便子视图控制器保存和恢复自己的状态。那么如何防止 UISplitViewController 恢复自己的状态,或者覆盖这种行为呢?

【问题讨论】:

    标签: ios uiviewcontroller ios8 uisplitviewcontroller state-restoration


    【解决方案1】:

    我通过继承 UISplitViewController 并覆盖 - (void)decodeRestorableStateWithCoder:(NSCoder *)coder 来解决这个问题。这样拆分视图控制器没有机会恢复其视图,但其子视图控制器仍参与状态恢复。

    【讨论】:

      【解决方案2】:

      实现 UI 状态恢复时需要做的第一件事是从使用 didFinishLaunchingWithOptions 更改为 willFinishLaunchingWithOptions。如果您现在在 willFinish 中设置委托,则将按预期调用折叠。问题可能是代理设置得太晚,没有你的特殊处理就已经崩溃了。

      另一个问题是,在横向和纵向时,控制器的恢复路径不同,因此可能会处于奇怪的状态。由于更改,它无法自动找到现有的详细视图控制器并创建新实例,并且由于详细信息项的配置错误,拆分视图委托可能会丢弃这两个或其中一个实例。在第 3 步的“重新创建您的视图控制器”下的 State Restoration 文档中,它说它会查找具有相同路径的已创建视图控制器,但在方向/特征更改后恢复时遗憾地失败,因为路径不同。因此它会退回到第 4 步并创建一个全新的空配置错误的详细控制器,这就是您看到控制器配置错误的原因。

      要了解恢复标识符路径,请在应用委托中实现 application:viewControllerWithRestorationIdentifierPath:coder: 并输出路径组件,您将在纵向上看到最后要恢复的样子:

      SplitViewController,
      MasterNavigationController,
      DetailNavigationController,
      DetailViewController
      

      ...对应于拆分视图控制器的单一层次结构主要(注意:DetailNavigationController 在此配置中是隐藏的嵌套导航控制器)。

      在景观中,最后两个要恢复的是:

      SplitViewController,
      MasterNavigationController,
      MasterViewController
      

      SplitViewController,
      DetailNavigationController,
      DetailViewController
      

      ...对应于拆分视图的主要和次要控制器层次结构。

      所以现在知道 DetailViewController 的恢复路径可能不同,您可以理解,如果您尝试自动恢复纵向路径,而情节提要已在横向中初始化,它将找不到该详细视图控制器并求助于创建一个新的一。所以我认为解决方案是帮它找到它,不管恢复路径是如何保存的:

      - (UIViewController *)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder{
          if([identifierComponents.lastObject isEqualToString:@"DetailViewController"]){
              UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
                  UINavigationController *secondaryNavigationController = splitViewController.viewControllers.lastObject;;
                  DetailViewController *detail = (DetailViewController *)secondaryNavigationController.viewControllers.firstObject;
              return detail;
          }
          return nil;
      }
      

      现在恢复将正确使用已正确配置的现有细节控制器,并且不会被拆分视图委托丢弃,从而导致您只剩下主控。

      这个问题的另一种表现方式是在恢复后看到两个细节控制器被推到导航堆栈上,如果你强制拆分视图委托不丢弃初始细节控制器,就会发生这种情况,当恢复创建另一个你最后推了两个!

      【讨论】:

        猜你喜欢
        • 2013-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-20
        • 2012-05-23
        • 1970-01-01
        • 1970-01-01
        • 2014-12-15
        相关资源
        最近更新 更多