实现 UI 状态恢复时需要做的第一件事就是从 using 更改didFinishLaunchingWithOptions
为willFinishLaunchingWithOptions
. 如果您现在在 willFinish 中设置委托,则将按预期调用折叠。问题可能是代理设置得太晚了,没有你的特殊处理它已经崩溃了。
另一个问题是,在横向和纵向时,控制器的恢复路径是不同的,因此可能会处于奇怪的状态。由于更改,它无法自动找到现有的详细视图控制器并创建新实例,并且由于详细信息项目的配置错误,拆分视图委托可能会丢弃这两个或其中一个实例。在第 3 步的“重新创建您的视图控制器”下的状态恢复文档中,它说它查找具有相同路径的已创建视图控制器,但在方向/特征更改后恢复时遗憾地失败,因为路径不同。所以它回退到第 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;
}
现在恢复将正确使用已正确配置的现有细节控制器,并且不会被拆分视图委托丢弃,从而导致您只剩下主控。
这个问题可以体现的另一种方式是看到两个细节控制器在恢复后被推到导航堆栈上,如果您强制拆分视图委托不丢弃初始细节控制器,并且当恢复创建另一个您最终得到的控制器时,就会发生这种情况两个推上去!