Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is viewWillDisappear called at the wrong time when using manual view containment?

This is how I am using the containment API. According to the docs is its correct.

[self.childViewController willMoveToParentViewController:nil];
[UIView animateWithDuration:0.25 animations:^{
    self.childViewController.view.frame = ... // View Animation
} completion:^(BOOL finished) {
    [self.childViewController.view removeFromSuperview]; // triggers `viewWillDisappear`
    [self.childViewController removeFromParentViewController];
}];

I expect viewWillDisappear to be called before the animation begins and viewDidDisappear to be called after the animation completes. However, they are both called in quick succession after the animation is complete.

Moving [self.childViewController.view removeFromSuperview]; to the animation block fixes this, but the code looks wrong:

[self.childViewController willMoveToParentViewController:nil];
[UIView animateWithDuration:0.25 animations:^{
    self.childViewController.view.frame = ... // View Animation
    [self.childViewController.view removeFromSuperview]; // triggers `viewWillDisappear`
} completion:^(BOOL finished) {
    [self.childViewController removeFromParentViewController];
}];

Does anyone know what the proper way to get viewWillDisappear to be called at the correct time is?

like image 511
Robert Avatar asked Jul 29 '14 17:07

Robert


1 Answers

The answer was to use – beginAppearanceTransition:animated: & endAppearanceTransition

If you are implementing a custom container controller, use this method to tell the child that its views are about to appear or disappear. Do not invoke viewWillAppear:, viewWillDisappear:, viewDidAppear:, or viewDidDisappear: directly.

The corrected code:

[self.childViewController willMoveToParentViewController:nil];
[self.childViewController beginAppearanceTransition:NO animated:YES];
[UIView animateWithDuration:0.25 animations:^{
    self.childViewController.view.frame = ... 
} completion:^(BOOL finished) {
    [self.childViewController.view removeFromSuperview]; 
    [self.childViewController removeFromParentViewController];
    [self.childViewController endAppearanceTransition];
}];
like image 75
Robert Avatar answered Sep 24 '22 13:09

Robert