问题:重新启动时,所选选项卡似乎按预期还原,但所述选项卡内的导航层次结构不是.
发展:
>我首先开始使用项目模板“基于标签的应用程序”.
>接下来,我将恢复ID添加到子视图控制器和标签栏控制器.
>在app委托中,我实现了应用程序(_:shouldSaveApplicationState :)和应用程序(_:shouldRestoreApplicationState :).
然后我运行应用程序,切换到第二个(右)选项卡,点击主页,终止. o重新启动,显示右侧选项卡(如预期).到现在为止还挺好.
>接下来,我转到故事板并将两个子视图控制器嵌入相应的导航控制器中,并为这些控制器分配恢复ID.
我运行应用程序,恢复仍然有效.还好.
>接下来,我添加一个“细节”视图控制器;它的类是故事板的UIViewController的自定义子类,具有配置调试标签内容及其视图背景颜色的属性.
>我在每个选项卡的顶视图控制器上放置了一个“显示详细信息…”按钮,并从每个选项卡创建一个segue到(共享)详细视图控制器中.所以现在我的故事板看起来像一个六边形(同样,两个segues都有在Interface Builder中设置的标识符).因此,左右顶视图控制器共享相同类型的“细节”视图控制器.在展示中,它被配置为区别于它被推动的位置(参见下一点).
>在每个顶视图控制器的prepareForSegue(_:sender :)方法中,我以不同的方式配置推送的详细信息视图控制器:不同的文本和背景颜色(分别为“左”和“蓝”,“右”和红色).
>我向详细视图控制器添加了代码,以保存和恢复文本和背景颜色属性的状态:encodeRestorableStateWithCoder(_ :)和decodeRestorableStateWithCoder(_ :).此外,我实现了viewDidLoad(),以便在视图中反映这些属性的值.每当它被实例化并通过segue推入导航时,首先设置属性然后用于在viewDidLoad()中配置视图.每当在恢复期间实例化时,属性都在decodeRestorableStateWithCoder(_ :)中设置,并且类似地在viewDidLoad()中使用.
…但是当我运行此代码时,最后选择的选项卡将被恢复,但仅限于顶视图控制器 – 左侧或右侧 – 而不是详细信息.有趣的是,最后设置到细节视图控制器的背景颜色瞬间闪烁.
我在encodeRestorableStateWithCoder(_ :)和decodeRestorableStateWithCoder(_ :)中放置了断点,但只执行了第一个(编码).
>想知道可能缺少什么,我继续实施app delegate的应用程序(_:viewControllerWithRestorationIdentifierPath:coder:)(总是返回nil,但是记录传递的路径组件).
关于是否需要此方法的文档不是很清楚,并且在任何情况下,除了细节之外的所有视图控制器似乎都可以完美地恢复,即使没有它.我添加了代码,根据最后一个路径组件(即该控制器的恢复ID)实例化每个视图控制器并返回它.
现在,调用decodeRestorableStateWithCoder(_ :),但导航仍然会在瞬间返回到选项卡的顶视图控制器.
那么发生了什么?在标签栏导航控制器应用程序中实现状态保存和恢复我缺少什么?
解决方法
>事实证明,在我的情况下,我不需要实现应用程序(_:viewControllerWithRestorationIdentifierPath:coder :). (见comments of this answer)
>我的encodeRestorableStateWithCoder(_ :)和decodeRestorableStateWithCoder(_ :)的实现
没有打电话给超级(如上面问题的accepted answer所示).
>最后,我得到了正确的视图控制器(细节),但其子视图的状态(文本标签内容和主视图背景颜色)处于初始的空状态(未恢复到其上一个状态-ie,文本标签)内容和bg颜色).正如在this question中提到的,viewDidLoad()在decodeRestorableStateWithCoder(_ :)之后没有被调用(就像我假设的那样),所以我从viewDidLoad()和decodeRestorableStateWithCoder(_ :)中调用一个公共方法来更新UI.
像往常一样,在搜索或尝试对我的代码进行足够的修改之前,我急忙发布一个问题(道歉……).
我希望这至少可以帮助别人.
像往常一样,我会等几天才接受我自己的答案,以防万一有人掏出更多的光.