1

设置

我有一个滑动菜单自定义容器视图控制器 ( MMDrawerController ) 控制一个中心视图控制器和一个滑出左侧菜单/抽屉。就像 Facebook 应用程序和其他数百个应用程序一样。

打开左侧的抽屉并点击菜单项会替换中心视图控制器。

什么工作

如果我打开应用程序,按下第一个中心视图控制器上的按钮(更改背景颜色),我可以终止应用程序并成功恢复背景颜色。完美的。

什么不工作

如果我选择另一个中心 vc 来加载(通过打开菜单/抽屉并选择一个菜单选项)然后终止应用程序,应用程序将不会恢复到该视图控制器。

我在做什么

在我的父视图控制器中,我正在编码左侧和中心视图控制器,以便我可以在恢复时重新创建它们。

- (void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
    [coder encodeObject:self.centerViewController forKey:@"centerVC"];
    [coder encodeObject:self.leftDrawerViewController forKey:@"leftDrawerVC"];
    [super encodeRestorableStateWithCoder:coder];
}

- (void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
    // if I don't change the center view controller, these values
    // get logged out as expected
    NSLog(@"leftDrawer: %@", [coder decodeObjectForKey:@"leftDrawerVC"]);
    NSLog(@"center: %@", [coder decodeObjectForKey:@"centerVC"]);
    [super decodeRestorableStateWithCoder:coder];
}

在我更改第一个中心视图控制器颜色的流程中,在解码期间我可以成功返回中心并离开视图控制器。但是,在我选择要加载的新中心 vc 的流程中,在解码期间这些对象为零。

如何设置我的自定义容器视图控制器以正确编码对其子项的引用,以保证在解码时将它们取回?

更新 1

使用restoreArchiveTool 在运行无法正确恢复的场景后,我检查了存档,并且存档实际上包含我期望的编码对象的层次结构。我仍然无法弄清楚为什么那些以前编码的视图控制器在解码过程中最终为空。

更新 2 如果您查看此要点的评论部分,您会发现所有正确的编码/解码调用似乎都在保存和恢复时发生。我想知道在我的应用程序委托中,当我最初设置我的根视图控制器(mmdrawercontroller 的实例)时,如果我以某种方式破坏了状态恢复?这就是我正在做的事情:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UINavController *centerNav = [[UINavController alloc] initWithRootViewController:[FeaturedViewController new]];
    centerNav.restorationIdentifier = @"centerNav";
    UINavigationController *leftDrawerNavController = [[UINavigationController alloc] initWithRootViewController:[LeftDrawerViewController new]];
    leftDrawerNavController.restorationIdentifier = @"leftDrawerNav";

    MMDrawerController *drawerViewController = [[MMDrawerController alloc] initWithCenterViewController:centerNav leftDrawerViewController:leftDrawerNavController];

    // no restoration class, since this will always be created before state restoration resumes, and therefore will be found implicitly
    [drawerViewController setRestorationIdentifier:@"mmDrawer"];

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = drawerViewController;
    self.window.restorationIdentifier = NSStringFromClass([UIWindow class]);
    self.window.backgroundColor = [UIColor whiteColor];

    [self.window makeKeyAndVisible];
    return true;
}
4

1 回答 1

1

我对 MMDrawerController 进行了类似的操作,并且认为问题在于您没有为 UIKit 提供一种在恢复状态时创建所有可能的中心视图控制器的方法。请注意,当您对控制器进行编码时,保存的只是该控制器的恢复 ID。要在您下次启动应用程序时恢复 UIKit 需要能够获取控制器的实例——它不会自己创建一个。它将尝试各种方法来获取所述实例,如下所示:

http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/StatePreservation/StatePreservation.html#//apple_ref/doc/uid/TP40007072-CH11-SW10

您的应用程序可能每次都创建默认的中心控制器(通过故事板或手动),以便一个工作。对于其他人,您可能需要实现恢复类或application:viewControllerWithRestorationIdentifierPath:coder:在您的委托中实现并让它返回正确类型的新实例。

于 2013-08-01T05:15:50.293 回答