标签栏和导航控制器应用程序中的状态恢复

Nic*_*ari 8 ios uistoryboard uikit-state-preservation ios9

目标:我正在尝试在基于选项卡控制器的应用程序上恢复状态(每个选项卡上都有导航控制器).

问题:重新启动时,所选选项卡似乎按预期还原,但所选选项卡内的导航层次结构不是.

发展:

  1. 我首先开始使用项目模板"基于标签的app".
  2. 接下来,我将恢复ID添加到子视图控制器和标签栏控制器.
  3. 在app委托中,我实现了application(_:shouldSaveApplicationState:)application(_:shouldRestoreApplicationState:).

然后我运行应用程序,切换到第二个(右)选项卡,点击主页,终止.重新启动,显示右侧选项卡(如预期).到现在为止还挺好.

  1. 接下来,我转到故事板并将两个子视图控制器嵌入相应的导航控制器中,并为这些控制器分配恢复ID.

我运行应用程序,恢复仍然有效.还好.

  1. 接下来,我添加一个"细节"视图控制器; 它的类是UIViewController故事板的自定义子类,具有配置调试标签内容及其视图背景颜色的属性.

  2. 我在每个选项卡的顶视图控制器上放置了一个"显示详细信息..."按钮,并从每个选项卡创建一个segue到(共享)详细视图控制器中.所以现在我的故事板看起来像一个六边形(同样,两个segues都有在Interface Builder中设置的标识符).因此,左右顶视图控制器共享相同类型的"细节"视图控制器.在展示中,它被配置为区别于它被推动的位置(参见下一点).

  3. 在每个顶视图控制器的prepareForSegue(_:sender:)方法中,我以不同的方式配置推送的细节视图控制器:不同的文本和背景颜色(分别为"左"和"蓝","右"和红色).

  4. 我将代码添加到详细视图控制器以保存和恢复文本和背景颜色属性的状态:encodeRestorableStateWithCoder(_:)decodeRestorableStateWithCoder(_:).此外,我实现了viewDidLoad()以便在视图中反映这些属性的值.每当它被实例化并通过segue推入导航时,首先设置属性然后用于配置视图viewDidLoad().无论何时在恢复期间实例化,都会设置属性decodeRestorableStateWithCoder(_:)并类似地使用viewDidLoad().

...但是当我运行此代码时,最后选择的选项卡将被恢复,但仅限于顶视图控制器 - 左侧或右侧 - 而不是详细信息.有趣的是,最后设置为细节视图控制器的背景颜色瞬间闪烁.

我放置断点中encodeRestorableStateWithCoder(_:)decodeRestorableStateWithCoder(_:),但只有其中第被执行(编码).

  1. 想知道可能会遗漏什么,我继续实施了app委托application(_:viewControllerWithRestorationIdentifierPath:coder:)(总是返回nil,但是记录了传递的路径组件).

关于是否需要这种方法的文档不是很清楚,并且在任何情况下,除了细节之外的所有视图控制器似乎都可以完美地恢复,即使没有它.我添加了代码,根据最后一个路径组件(即该控制器的恢复ID)实例化每个视图控制器并返回它.

现在,它decodeRestorableStateWithCoder(_:) 调用,但导航仍然会在瞬间返回到选项卡的顶视图控制器.

那么发生了什么?在Tab栏+导航控制器应用程序中实现状态保存和恢复我缺少什么?

Nic*_*ari 6

修复:所以,我的代码有几个问题......

  1. 事实证明,就我而言,我不需要实施application(_:viewControllerWithRestorationIdentifierPath:coder:).(见这个答案评论)

  2. 我的实现encodeRestorableStateWithCoder(_:)decodeRestorableStateWithCoder(_:) 没有调用super(如上面问题的接受答案中所建议的).

  3. 最后,我得到了正确的视图控制器(细节),但其子视图的状态(文本标签内容和主视图背景颜色)处于初始状态(未恢复到其最后状态-ie,文本标签内容)和bg颜色).正如在这个问题中所提到的,viewDidLoad()之后没有被调用decodeRestorableStateWithCoder(_:)(就像我假设的那样),所以我从两者中调用一个公共方法viewDidLoad()decodeRestorableStateWithCoder(_:)更新UI.

像往常一样,在我的代码中搜索或尝试足够的修改之前,我急忙发布一个问题(道歉......).

我希望这至少可以帮助别人.

像往常一样,我会等几天才接受我自己的答案,以防万一有人掏出更多的光.