目标:我正在尝试恢复基于选项卡控制器的应用程序的状态(每个选项卡上都有导航控制器)。
问题:重新启动时,所选选项卡似乎已按预期恢复,但所述选项卡内的导航层次结构却没有。
发展:
- 我首先从项目模板“基于选项卡的应用程序”开始。
- 接下来,我将恢复 ID 添加到子视图控制器和选项卡栏控制器。
- 在应用程序委托中,我实现了
application(_:shouldSaveApplicationState:)
和application(_:shouldRestoreApplicationState:)
.
我运行然后应用程序,切换到第二个(右)选项卡,回家,终止。o 重新启动,显示右侧选项卡(如预期的那样)。到目前为止,一切都很好。
- 接下来,我转到故事板并将两个子视图控制器嵌入到各自的导航控制器中,并为它们分配恢复 ID。
我运行该应用程序,恢复仍然有效。还好。
接下来,我添加一个“细节”视图控制器;它的类是
UIViewController
故事板的自定义子类,具有配置调试标签内容及其视图背景颜色的属性。我在每个选项卡的顶部视图控制器上放置了一个“显示详细信息...”按钮,并从每个选项卡创建一个 segue 到(共享)详细视图控制器。所以现在我的故事板看起来像一个六边形(另外,两个 segue 都在 Interface Builder 中设置了标识符)。因此,左右顶视图控制器共享相同类型的“细节”视图控制器。在展示时,它被配置为区别于它被推送的位置(见下一点)。
在每个顶视图控制器的
prepareForSegue(_:sender:)
方法中,我对推送的详细视图控制器进行了不同的配置:不同的文本和背景颜色(分别为“左”和蓝色,“右”和红色)。我在细节视图控制器中添加了代码来保存和恢复文本和背景颜色属性的状态:
encodeRestorableStateWithCoder(_:)
和decodeRestorableStateWithCoder(_:)
. 此外,我实施viewDidLoad()
以在视图中反映这些属性的值。每当它被实例化并通过 segue 推入导航时,首先设置属性,然后用于在viewDidLoad()
. 每当它在恢复过程中被实例化时,属性都会被设置decodeRestorableStateWithCoder(_:)
并类似地用于viewDidLoad()
.
...但是当我运行此代码时,最后选择的选项卡会恢复,但只能恢复到顶部视图控制器-left 或 right-,而不是 detail。有趣的是,最后为细节视图控制器设置的背景颜色会瞬间闪烁。
encodeRestorableStateWithCoder(_:)
我在and中放置了断点decodeRestorableStateWithCoder(_:)
,但只有第一个被执行(encode)。
- 想知道可能缺少什么,我继续实现了应用程序委托
application(_:viewControllerWithRestorationIdentifierPath:coder:)
(始终返回 nil,但记录传递的路径组件)。
关于是否需要这种方法,文档不是很清楚,并且在任何情况下,除了细节之外的所有视图控制器似乎都可以完美地恢复,即使没有它。我添加了代码以根据最后一个路径组件(即,该控制器的恢复 ID)实例化每个视图控制器并返回它。
现在,调用了decodeRestorableStateWithCoder(_:)
,但导航仍会在一瞬间后返回到选项卡的顶部视图控制器。
那么发生了什么?在选项卡栏 + 导航控制器应用程序中实现状态保存和恢复我缺少什么?