UITabBarController的iOS状态恢复不会还原子视图控制器或选定的索引

时间:2015-07-22 06:21:11

标签: ios swift uitabbarcontroller state tabbarcontroller

(这是我第一次在StackOverflow上提问,如果有问题请原谅我)

我的问题归结为无法正确恢复UITabBarController的状态。这是一个基于选项卡的应用程序,我没有使用Storyboard。

我选择了恢复状态。我已经在各自的ViewController方法中为我的所有自定义init提供了唯一的恢复标识符和恢复类。

对于UITabBarController,我在创建时为其提供了唯一的恢复标识符。因为我没有给它一个恢复类,所以我在app delegate中实现了以下代码:

- (UIViewController *)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder 
{
    UITabBarController *vc = [[UITabBarController alloc] init];

    vc.restorationIdentifier = [identifierComponents lastObject];

    if ([identifierComponents count] == 1) {
        self.window.rootViewController = vc;
    }

    return vc;
}

我在其他应用中使用了相同的方法来恢复NavigationController的状态,一切顺利。但是,当我使用TabBarController为此应用程序执行此操作时,应用程序将以空TabBarController启动(TabBarController已恢复,但它不会还原它的子视图控制器)。

这对我来说并不是一个巨大的震撼,我想只是天生UITabBarController s不会保留对子视图控制器的引用,而不是状态恢复的选定选项卡索引。但是,尽管在网上搜索了很多个小时,但我无法解释如何保留TabBarController的状态(没有storyboard)。如何做到这一点的任何帮助将非常感激。

同样,如果我没有提供足够的细节或者不够清楚,我很抱歉。请让我知道你的答案需要什么,我会提供。我知道我没有提供太多的代码,但我真的只需要说明如何在没有故事板的情况下保留基于Tab的应用程序的状态。它不需要根据我的具体情况量身定制;我将能够自己应用一般过程。

谢谢!

5 个答案:

答案 0 :(得分:1)

您可以使用NSUserDefaults来设置状态,如果您大部分时间都使用它,则应该全局分配tabBar而不是方法。如果每次都初始化tabBar,那么它将不会说明先前的状态。因为创建对该对象的新引用将丢弃先前的更改,并且您可能无法保存状态。

答案 1 :(得分:1)

我也遇到了这个问题,因为这是我第一次实施状态恢复范式,想知道我是否做错了。

在我的情况下,我基于持久状态(登录状态等)以编程方式在application willFinishLaunchingWithOptions中创建视图控制器层次结构(在执行状态恢复之前)。我有一个根标签栏控制器,我想存储所选索引(至少),我期望默认的encodeRestorableStatedecodeRestorableState方法来处理这个问题。他们没有。

所以我最终为此目的继承了UITabBarController的子类。它在Swift中,但我认为你可以阅读它。添加断点以确保调用这些方法。

class LPTabBarController: UITabBarController
{
    let selectedIndexKey = "selectedIndexKey"

    override func encodeRestorableState(with coder: NSCoder) {
        coder.encode(selectedIndex, forKey: selectedIndexKey)
        super.encodeRestorableState(with: coder)
    }

    override func decodeRestorableState(with coder: NSCoder)
    {
        super.decodeRestorableState(with: coder)
        selectedIndex =  coder.decodeInteger(forKey: selectedIndexKey)
    }
}

作为旁注,我认为NSUserDefaults不应该用于这种短暂的UI状态作为选定的标签栏索引。

答案 2 :(得分:0)

您需要对每个孩子的视图控制器进行编码。 但iOS文档声明你不解码这些 - 这一点会自动发生。

override func encodeRestorableStateWithCoder(coder: NSCoder) {
    coder.encodeObject(child0VC, forKey:"child0VC")
    coder.encodeObject(child1VC, forKey:"child1VC")
    super.encodeRestorableStateWithCoder(coder)
}

答案 3 :(得分:0)

UISplitViewController具有相同的问题。您可以通过自己对childViewControllers进行编码/解码来解决此问题。

答案 4 :(得分:0)

我的发现是UITabBarController用恢复标识符存储选择(至少在iOS 14上如此)。

如果您要恢复的只是先前选择的标签,则:

  • 将恢复标识符分配给标签栏控制器及其子对象
  • -application:willFinishLaunchingWithOptions:中创建视图控制器层次结构(didFinish太晚了,因为它在恢复过程之后正在运行)

通过上述操作,状态还原应该能够使用还原标识符来查找先前选择的子级(由常规启动逻辑初始化),并且标签栏控制器会自行还原选择。