简体   繁体   English

iOS状态保存和容器视图

[英]iOS state preservation and container views

I have a view controller in a storyboard that is using a container view. 我在故事板中有一个使用容器视图的视图控制器。 Both have restoration identifiers set. 两者都具有恢复标识符集。 The parent is being saved and restored just fine. 父母正在被保存并恢复正常。 The child however is not. 然而,孩子不是。 Neither -encodeRestorableStateWithCoder: or -decodeRestorableStateWithCoder: are being called on the child view controller. 在子视图控制器上没有-encodeRestorableStateWithCoder:-decodeRestorableStateWithCoder: .

What's the correct way to save child view controllers that are created with a view container? 保存使用视图容器创建的子视图控制器的正确方法是什么? I can save the child view controller in the parents -encodeRestorableStateWithCoder: , which will cause it to be saved, but I don't have a way of using it during a restore. 我可以将子视图控制器保存在父级-encodeRestorableStateWithCoder: ,这将导致它被保存,但我没有办法在恢复期间使用它。

Container view controller " does not automatically save references to any contained child view controllers. If you are implementing a custom container view controller, you must encode the child view controller objects yourself if you want them to be preserved ". 容器视图控制器“ 不会自动保存对任何包含的子视图控制器的引用。如果要实现自定义容器视图控制器,则必须自己编码子视图控制器对象(如果要保留它们) ”。

There are simple rules that i found: 我发现有简单的规则:

1.Embedded(child) view controller should already be created and added to parent view controller at the state preservation process. 1.已经创建了嵌入式(子)视图控制器,并在状态保存过程中将其添加到父视图控制器中。 So, do not have to do anything if you use storyboard otherwise you'll have to instantiate child view controller and add it manually: 因此,如果您使用storyboard,则不必执行任何操作,否则您必须实例化子视图控制器并手动添加它:

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

You can add child view at -viewDidLoad or later. 您可以在-viewDidLoad或更高版本中添加子视图。 Use self.childVC.view.frame = [self frameForChildController]; [self.view addSubview:self.childVC.view]; 使用self.childVC.view.frame = [self frameForChildController]; [self.view addSubview:self.childVC.view]; self.childVC.view.frame = [self frameForChildController]; [self.view addSubview:self.childVC.view]; for this. 为了这。

2.You no need to save the child view controller in the parent's -encodeRestorableStateWithCoder: himself, but you should encode a reference to that object using -encodeObject:forKey: . 2.您不需要将子视图控制器保存在父级的-encodeRestorableStateWithCoder: ,但您应该使用-encodeObject:forKey:编码对该对象的引用 If you have reference you can do it like this: 如果你有参考,你可以这样做:

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

see https://stackoverflow.com/a/13279703/2492707 to get reference to child VC if you use Storyboard. 如果您使用Storyboard,请参阅https://stackoverflow.com/a/13279703/2492707以获取对子VC的引用。 Or you can write something simple like this: 或者你可以写一些简单的东西:

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

3. Embedded(child) view controller should already be created and added to parent view controller at the state restoration process . 3. 应在状态恢复过程中创建嵌入式(子)视图控制器并将其添加到父视图控制器 So, if you did everything in the first paragraph, there is nothing more to do here. 所以,如果你在第一段中做了所有事情,那么这里没有更多的事要做了。

4."In this case, however, we do not decode child view controller. We could , but in fact we don't need it.The MyChildViewController object will restore its own state. We only encoded this reference in order to get the runtime to walk the chain down to the MyChildViewController instance and do save-and-restore on it". 4.“但是,在这种情况下,我们不解码子视图控制器。我们可以 ,但实际上我们不需要它.MyChildViewController对象将恢复其自己的状态。我们只编码此引用以获取运行时将链向下走到MyChildViewController实例并对其进行保存和恢复“。

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

This book helps me for understanding state preservation with container views. 本书帮助我理解状态保存与容器的观点。 Also look for a good example for this book 还要为本书寻找一个好例子

I think the answer is in the documentation It is said: 我认为答案在文档中据说:

" The UIViewController class saves a reference to the presented view controller and the storyboard (if any) that was used to create the view controller. The view controller also asks the views in its view hierarchy to save out any relevant information. However, this class does not automatically save references to any contained child view controllers. If you are implementing a custom container view controller, you must encode the child view controller objects yourself if you want them to be preserved. " “UIViewController类保存对用于创建视图控制器的呈现视图控制器和故事板(如果有)的引用。视图控制器还要求视图层次结构中的视图保存任何相关信息。 但是,此类不会自动保存对任何包含的子视图控制器的引用。如果要实现自定义容器视图控制器,则必须自己编码子视图控制器对象(如果要保留它们)。

So you could do something like that: 所以你可以这样做:

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

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

And in MyChildViewController do not call super :) 而在MyChildViewController中不要调用super :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM