19

我在故事板中有一个使用容器视图的视图控制器。两者都设置了恢复标识符。父母正在被保存和恢复得很好。然而孩子不是。在子视图控制器上既不调用-encodeRestorableStateWithCoder:也不调用。-decodeRestorableStateWithCoder:

保存使用视图容器创建的子视图控制器的正确方法是什么?我可以将子视图控制器保存在 parents-encodeRestorableStateWithCoder:中,这将导致它被保存,但我无法在恢复期间使用它。

4

2 回答 2

20

容器视图控制器“不会自动保存对任何包含的子视图控制器的引用。如果您正在实现自定义容器视图控制器,如果您希望它们被保留,您必须自己编码子视图控制器对象”。

我发现了一些简单的规则:

1.Embedded(子)视图控制器应该已经创建并在状态保存过程中添加到父视图控制器。因此,如果您使用故事板,则不必做任何事情,否则您必须实例化子视图控制器并手动添加它:

-(void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"Did load");
    MyChildViewController *childViewController = [MyChildViewController new];
    [self addChildViewController:childViewController];
    [childViewController didMoveToParentViewController:self];
    self.childVC = childViewController;
}

-viewDidLoad您可以在或以后添加子视图。用于self.childVC.view.frame = [self frameForChildController]; [self.view addSubview:self.childVC.view];此。

2.您无需将子视图控制器保存在父视图控制器中-encodeRestorableStateWithCoder:但您应该使用. 如果你有参考,你可以这样做:-encodeObject:forKey:

-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
    NSLog(@"Encode");
    UIViewController *childViewController = self.childVC;
    [coder encodeObject:childViewController forKey:@"ChildVC"];
    [super encodeRestorableStateWithCoder:coder];
}

如果您使用 Storyboard,请参阅https://stackoverflow.com/a/13279703/2492707以获取对子 VC 的引用。或者你可以写一些像这样简单的东西:

-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
    NSLog(@"Encode");
    UIViewController *childViewController = [self.childViewControllers objectAtIndex:0]; //[self.childViewControllers lastObject];
    [coder encodeObject:childViewController forKey:@"ChildVC"];
    [super encodeRestorableStateWithCoder:coder];
}

3.嵌入式(子)视图控制器应该已经创建并在状态恢复过程中添加到父视图控制器。因此,如果您在第一段中做了所有事情,那么这里就没有什么可做的了。

4.“然而,在这种情况下,我们不解码子视图控制器。我们可以,但实际上我们不需要它。MyChildViewController 对象将恢复它自己的状态。我们只对这个引用进行编码以获得运行时将链向下移动到 MyChildViewController 实例并对其进行保存和恢复”。

-(void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
    NSLog(@"Decode");
    [super decodeRestorableStateWithCoder:coder];
}

本书帮助我理解容器视图的状态保存。也为这本书寻找一个很好的例子

于 2013-06-24T07:32:54.383 回答
-1

我认为答案在文档 中说:

" UIViewController 类保存对呈现的视图控制器和用于创建视图控制器的情节提要(如果有)的引用。视图控制器还要求其视图层次结构中的视图保存任何相关信息。然而,这个类不会自动保存对任何包含的子视图控制器的引用。如果您正在实现自定义容器视图控制器,如果您希望保留子视图控制器对象,则必须自己对它们进行编码。 "

所以你可以做这样的事情:

-(void)encodeRestorableStateWithCoder:(NSCoder *)coder {
    [super encodeRestorableStateWithCoder:coder];
    [self.myChildViewController encodeRestorableStateWithCoder:coder];
}

-(void)decodeRestorableStateWithCoder:(NSCoder *)coder {
    [super decodeRestorableStateWithCoder:coder];
    [self.myChildViewController decodeRestorableStateWithCoder:coder];
}

并且在 MyChildViewController 中不要调用 super :)

于 2013-05-20T10:33:56.963 回答