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