iOS state preservation and container views

前端 未结 2 1846
清歌不尽
清歌不尽 2021-02-01 20:33

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 howev

相关标签:
2条回答
  • 2021-02-01 20:56

    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. So, do not have to do anything if you use storyboard otherwise you'll have to instantiate child view controller and add it manually:

    -(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. Use 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:. 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. 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. 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".

    -(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

    0 讨论(0)
  • 2021-02-01 20:58

    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."

    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 :)

    0 讨论(0)
提交回复
热议问题