现在,这个问题部分地被问了很多,但没有人真正考虑如何(或何时)发送消息 -viewWillDisappear 和 -viewDidDisappear 。几乎每个示例都使用以下设计:
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationCurveEaseOut
animations:^{
yourView.alpha = 0;
}completion:^(BOOL finished){
[yourView removeFromSuperview]; // Called on complete
}];
问题是这些消息都会在动画结束时发送!
现在,-addSubview 可以进行动画处理(如果放在动画 block 内),它将发送相应的消息(-viewWillAppear & -viewDidAppear )有正确的时差。所以很自然地,人们会将 -removeFromSuperview 放在动画 block 中。这将正确发送消息,但实际上 View 会立即被移除,从而制作动画......好吧,它不会动画,因为没有任何动画可言!
这是苹果故意的吗?如果是,为什么?你如何正确地做到这一点?
谢谢!
编辑。
只是为了澄清我在做什么:
我得到了一个自定义的 segue,从顶部垂直地为 Child-ViewController 设置动画,它可以使用以下代码按预期工作:
-(void)perform{
UIViewController *srcVC = (UIViewController *) self.sourceViewController;
UIViewController *destVC = (UIViewController *) self.destinationViewController;
destVC.view.transform = CGAffineTransformMakeTranslation(0.0f, -destVC.view.frame.size.height);
[srcVC addChildViewController:destVC];
[UIView animateWithDuration:0.5f
animations:^{
destVC.view.transform = CGAffineTransformMakeTranslation(0.0f, 0.0f);
[srcVC.view addSubview:destVC.view];
}
completion:^(BOOL finished){
[destVC didMoveToParentViewController:srcVC];
}];
}
这里将按以下顺序发生(感谢 -addSubview 在动画 block 内):
- 添加childView(会自动调用
-willMoveToParentViewController )
-addSubview 将调用 -viewWillAppear
- 动画结束后,
-addSubview 会调用-viewDidAppear
- 在完成 block 中手动调用
-didMoveToParentViewController
以上是确切的预期行为(就像内置转换的行为一样)。
使用以下代码执行上述 segue 但向后(使用 unwindSegue):
-(void)perform{
UIViewController *srcVC = (UIViewController *) self.sourceViewController;
srcVC.view.transform = CGAffineTransformMakeTranslation(0.0f, 0.0f);
[srcVC willMoveToParentViewController:nil];
[UIView animateWithDuration:5.5f
animations:^{
srcVC.view.transform = CGAffineTransformMakeTranslation(0.0f, -srcVC.view.frame.size.height);
}
completion:^(BOOL finished){
[srcVC.view removeFromSuperview]; // This can be done inside the animations-block, but will actually remove the view at the same time ´-viewWillDisappear´ is invoked, making no sense!
[srcVC removeFromParentViewController];
}];
}
流程是这样的:
- 手动调用
-willMoveToParentView:nil 通知它将被移除
- 动画结束后,
-viewWillDisappear & -viewDidDisappear 会同时被调用(错误!),-removeFromParentViewController 会自动调用-didMoveToParentViewController:nil .
如果我现在将 -removeFromSuperview 移动到动画 block 中,事件将被正确发送,但 View 会在动画开始而不是动画结束时被移除(这是部分这是没有意义的,遵循 -addSubview 的行为方式)。
Best Answer-推荐答案 strong>
您的问题是关于删除 View Controller ,因为 viewWillDisappear 和 viewDidDisappear 是 View Controller 的方法。
viewWillDisappear: 将从完成 block 中调用,而不是更早,因为这是您说要从主视图中删除 subview 的地方。
如果您想在该点之前删除某些属性,则在子 Controller 中重写 willMoveToParentViewController: 方法。此方法将在动画 block 之前调用。
下面是代码示例:
//Prepare view for removeing.
[self.childViewController willMoveToParentViewController:nil];
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
self.childViewController.view.alpha = 0;
}completion:^(BOOL finished){
[self.childViewController.view removeFromSuperview];
[self.childViewController didMoveToParentViewController:self];
}];
所以,流程将是:
- 第一个
willMoveToParentViewController: 会调用 nil 参数
- 动画 block 将启动, View 会将其 alpha 属性设置为 0
- 动画结束后,完成 block 将开始执行...
[self.childViewController.view removeFromSuperview]; 会先被调用
- 然后会调用childViewController中的
viewWillDissapear:
- 然后
[self.childViewController didMoveToParentViewController:self];
- 最后
viewDidDissapear: in childViewController 将执行。
此流程的预请求是您使用以下代码嵌入 childViewController:
[self addChildViewController:self.childViewController];
[self.view addSubview:self.childViewController.view];
[self.childViewController didMoveToParentViewController:self];
关于ios - UIView removeFromSuperview 内动画正确,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/19883568/
|