使用手动视图包含时,为什么在错误的时间调用viewWillDisappear?

Rob*_*ert 7 cocoa-touch objective-c uiviewcontroller ios

这就是我使用包含API的方式.根据文档是正确的.

[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];
}];
Run Code Online (Sandbox Code Playgroud)

我期望viewWillDisappear在动画开始之前viewDidDisappear调用,并在动画完成后调用.但是,在动画完成后,它们都会快速连续调用.

移动[self.childViewController.view removeFromSuperview];到动画块修复此问题,但代码看起来错误:

[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];
}];
Run Code Online (Sandbox Code Playgroud)

有谁知道viewWillDisappear在正确的时间被调用的正确方法是什么?

Rob*_*ert 11

答案是使用– beginAppearanceTransition:animated:&endAppearanceTransition

如果要实现自定义容器控制器,请使用此方法告诉子项其视图将要显示或消失.不要直接调用viewWillAppear:,viewWillDisappear:,viewDidAppear:或viewDidDisappear :.

更正后的代码:

[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];
}];
Run Code Online (Sandbox Code Playgroud)

  • Typo,我认为:应该将`self.viewController`的消息发送到`self.childViewController`,因为外观转换消息应该发送给正在转换的子节点. (2认同)