动画完成时,是否应将success值传入completeTransition?
关于UIViewController转场中success与transitionWasCancelled的误区解析
先明确两个值的本质含义
- UIView.animate completion中的
success:这个布尔值仅针对当前动画本身,标识动画是否完整执行完毕。如果动画没有被系统(比如内存紧张)或代码(比如调用layer.removeAllAnimations())中途打断,顺利走完整个duration,它就是true;反之则是false。 !transitionContext.transitionWasCancelled:这个值属于转场流程的全局状态,标识整个转场操作是否成功完成。当用户触发转场取消(比如侧滑返回中途松手)、系统主动取消转场时,transitionWasCancelled会变为true,此时!transitionWasCancelled就是false,代表转场失败;如果转场全程没有被取消,不管动画是否出问题,这个值都是true。
你的核心误区
你把动画层面的"完成状态"和转场层面的"成功状态"混为一谈了:
- 动画完成(success=true)≠ 转场成功:比如转场到一半,用户取消了转场,此时
transitionWasCancelled已经是true,但UIView的动画可能还会继续执行到结束,这时候success是true,但转场实际已经被取消,不能把success传给completeTransition,否则会导致系统的转场状态混乱(比如原控制器被错误地销毁)。 - 动画未完成(success=false)≠ 转场失败:比如动画中途被系统意外中断,但转场本身没有被取消,这时候即使success是
false,也需要调用completeTransition(true)来告诉系统转场成功完成,否则会导致控制器栈状态异常。
正确的做法
不管UIView动画的success是什么值,都应该传入!transitionContext.transitionWasCancelled给completeTransition。因为转场的成功与否由转场上下文的状态决定,和单个动画是否完成没有直接关联。
修正后的代码示例:
UIView.animate(withDuration: totalDuration) { fromVC.view.alpha = 0 } completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }
内容的提问来源于stack exchange,提问作者Dan Morrow
相关产品推荐
相关产品推荐

