繁体   English   中英

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

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

这就是我使用包含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];
}];

我希望在动画开始之前viewDidDisappear 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];
}];

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

答案是使用– 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];
}];

您没有通知childViewController已移动到parentViewController。

[yourViewController didMoveToParentViewController:self]

并在[self.childViewController willMoveToParentViewController:nil]; 你没有提到谁将成为parentViewController。 指示添加childViewController的时间是一个很好的做法。 然后iOS应该知道何时触发viewWillDisappear

您正在通知viewController将移动到parentViewController,但如果您指明parentViewController是您的代码将按预期工作,则您不会指示whoViewController是谁。

当视图准备好离开parentView时,ViewWillDissappear将被触发。 这将在您的parentViewController或viewController的下一个willLayoutSubviews执行中发生,具体取决于viewControllers的层次结构

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

试试吧

这是一个Swift版本。 它将beginAppearanceTransition置于动画关闭中,因此您可以获得类似UINavigationController行为:您可以在子视图控制器的viewWillDisappear调整可动画视图属性并自动获取动画。

let animator = UIViewPropertyAnimator(duration: 0.5, dampingRatio: 1) {
    childViewController.willMove(toParentViewController: self)
    childViewController.beginAppearanceTransition(false, animated: true)
    childViewController.view.frame = ... // View Animation
}
animator.addCompletion { _ in
    childViewController.view.removeFromSuperview()
    childViewController.endAppearanceTransition()
    childViewController.removeFromParentViewController()
}
animator.startAnimation()

注意endAppearanceTransition必须被调用后view.removeFromSuperview否则系统将发送重复的viewWillDisappear viewDidDisappear方法给您的孩子视图控制器。

暂无
暂无

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

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