是否有可能取消一个UIView动画,而它正在进行中?或者我必须降到CA级别?
例如,我做过这样的事情(可能设置了一个结束动画动作):
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties
// set view properties
[UIView commitAnimations];
但是在动画完成之前,我得到动画结束事件,我想取消它(缩短它)。这可能吗?在谷歌上搜索一下,会发现一些人问了同样的问题,但没有答案——还有一两个人猜测这是不可能的。
如果你正在寻找灵活的动画,可以根据你的需要开始和停止,使用UIViewPropertyAnimator。
示例代码
let sampleView = UIView()
lazy var animator: UIViewPropertyAnimator = {
let animator = UIViewPropertyAnimator(duration: 1.2, curve: .easeOut)
animator.isInterruptible = true
return animator
}()
// add and your animatable property
animator.addAnimations {
// what you need to animate add here
sampleView.alpha = 0
}
// start animation
animator.startAnimation(afterDelay: 0.5)
如果你需要在动画中间停下来。它将在当前状态下停止动画。
// stop animation
if animator.isRunning {
animator.stopAnimation(true)
}
当我使用UIStackView动画时,除了removeAllAnimations()之外,我需要将一些值设置为初始值,因为removeAllAnimations()可以将它们设置为不可预知的状态。我有stackView与view1和view2在里面,一个视图应该是可见的和一个隐藏:
public func configureStackView(hideView1: Bool, hideView2: Bool) {
let oldHideView1 = view1.isHidden
let oldHideView2 = view2.isHidden
view1.layer.removeAllAnimations()
view2.layer.removeAllAnimations()
view.layer.removeAllAnimations()
stackView.layer.removeAllAnimations()
// after stopping animation the values are unpredictable, so set values to old
view1.isHidden = oldHideView1 // <- Solution is here
view2.isHidden = oldHideView2 // <- Solution is here
UIView.animate(withDuration: 0.3,
delay: 0.0,
usingSpringWithDamping: 0.9,
initialSpringVelocity: 1,
options: [],
animations: {
view1.isHidden = hideView1
view2.isHidden = hideView2
stackView.layoutIfNeeded()
},
completion: nil)
}
没有一个解决方案对我有效。我用这种方式解决了我的问题(我不知道这是否是正确的方式?),因为我在调用这个太快的时候有问题(当以前的动画还没有完成的时候)。我通过customAnim块传递我想要的动画。
extension UIView
{
func niceCustomTranstion(
duration: CGFloat = 0.3,
options: UIView.AnimationOptions = .transitionCrossDissolve,
customAnim: @escaping () -> Void
)
{
UIView.transition(
with: self,
duration: TimeInterval(duration),
options: options,
animations: {
customAnim()
},
completion: { (finished) in
if !finished
{
// NOTE: This fixes possible flickering ON FAST TAPPINGS
// NOTE: This fixes possible flickering ON FAST TAPPINGS
// NOTE: This fixes possible flickering ON FAST TAPPINGS
self.layer.removeAllAnimations()
customAnim()
}
})
}
}
如果你正在寻找灵活的动画,可以根据你的需要开始和停止,使用UIViewPropertyAnimator。
示例代码
let sampleView = UIView()
lazy var animator: UIViewPropertyAnimator = {
let animator = UIViewPropertyAnimator(duration: 1.2, curve: .easeOut)
animator.isInterruptible = true
return animator
}()
// add and your animatable property
animator.addAnimations {
// what you need to animate add here
sampleView.alpha = 0
}
// start animation
animator.startAnimation(afterDelay: 0.5)
如果你需要在动画中间停下来。它将在当前状态下停止动画。
// stop animation
if animator.isRunning {
animator.stopAnimation(true)
}