iOS 8中的UISplitViewController状态恢复

时间:2014-09-15 14:47:46

标签: ios uiviewcontroller ios8 uisplitviewcontroller state-restoration

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

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

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

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:0)

实现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;
}

现在,还原将正确使用已正确配置的现有详细信息控制器,并且不会被拆分视图委托丢弃,从而导致您留在主视图中。

此问题可以体现的另一种方式是,还原后看到两个细节控制器被推到导航堆栈上,如果您强制拆分视图委托不要丢弃初始的细节控制器,并且还原创建另一个时,您会发生这种情况最终有两个推入!