iOS 8中的UISplitViewController状态恢复

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

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

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

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

问题在于,在景观和肖像中,修复路径是不同的,因此它处于一种奇怪的状态。 由于更改,它无法找到现有的详细信息视图控制器并创建新的视图控制器,并且由于详细信息项的配置错误,拆分视图委托可能会丢弃它们或其中之一。 在第3步“重新创建视图控制器”下的状态恢复文档中,它表示它会查找已创建的视图控制器,该路径控制器具有相同的路径,因为路径不同而在方向/特征更改后进行恢复时可能会失败。 所以它回到第4步并创建一个全新的空配置错误的细节控制器,这就是你看到控制器配置错误的原因。

要了解恢复标识符路径,请实现应用程序:viewControllerWithRestorationIdentifierPath:coder:在app委托中输出您将在纵向中看到的要恢复的最后一个路径组件,如下所示:

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

现在,恢复将正确使用已正确配置的现有详细信息控制器,并且拆分视图委托不会抛弃它,导致您与主服务器保持一致。

此问题可以表现的另一种方式是在恢复后看到两个细节控制器被推入导航堆栈,如果强制拆分视图委托不丢弃初始细节控制器,并且当修复创建另一个时,最终会导致两个推!