iOS 8中的UISplitViewController状态恢复

问题描述 投票:3回答:2

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

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

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

ios uiviewcontroller ios8 uisplitviewcontroller state-restoration
2个回答
4
投票

我通过子类化UISplitViewController并重写- (void)decodeRestorableStateWithCoder:(NSCoder *)coder来解决任何问题。这样,拆分视图控制器没有机会还原其视图,但是其子视图控制器仍参与状态还原。


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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.