iOS状态保存和容器视图

时间:2013-04-03 23:17:55

标签: iphone ios uikit-state-preservation

我在故事板中有一个使用容器视图的视图控制器。两者都具有恢复标识符集。父母正在被保存并恢复正常。然而,孩子不是。在子视图控制器上都没有调用-encodeRestorableStateWithCoder:-decodeRestorableStateWithCoder:

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

2 个答案:

答案 0 :(得分:17)

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

我发现有简单的规则:

1.嵌入式(子)视图控制器应该已经创建并在状态保存过程中添加到父视图控制器。因此,如果您使用storyboard,则不必执行任何操作,否则您必须实例化子视图控制器并手动添加它:

-(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];
}

This本书帮助我了解容器视图的状态保存。另外look是本书的一个很好的例子

答案 1 :(得分:-1)

我认为答案在documentation 据说:

“UIViewController类保存对用于创建视图控制器的呈现视图控制器和故事板(如果有)的引用。视图控制器还要求视图层次结构中的视图保存任何相关信息。< strong>但是,此类不会自动保存对任何包含的子视图控制器的引用。如果要实现自定义容器视图控制器,则必须自己对子视图控制器对象进行编码(如果要保留它们)。“

所以你可以这样做:

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

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

在MyChildViewController中不要调用super:)