我定义了UIDynamicAnimator属性:
lazy fileprivate var animator: UIDynamicAnimator = {
return UIDynamicAnimator(referenceView: self)
}()
自是UIView的子类;
在self类的扩展中,同一个文件,我有动画逻辑,它使用我的animator,添加UIDynamicBehavior项:
let pushBehavior = UIPushBehavior(items: [stampView], mode: .continuous)
//some settings
let dynamicItemBehavior = UIDynamicItemBehavior(items: [stampView])
//some settings
let gravityBehavior = UIGravityBehavior(items: [stampView])
//some settings
let collisionBehavior = UICollisionBehavior(items: [stampView])
//some settings
一切正常,但当我尝试停止所有带有removeAllBehaviors()动画的动画时,动画停止,但所有行为仍在animator.behaviors中。第二次调用时,数组变为空。
//======
对于我的pushBehavior,我添加了action,该action更改了var,表示我实现了目标点:
pushBehavior.action = { [unowned stampView] in
if stampView.center.x <= endPosition.x {
lastJump = true
}
}
在collisionBehavior委托方法中,我检查此变量并尝试使用removeAllBehaviors()停止动画
public func collisionBehavior(_ behavior: UICollisionBehavior, beganContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, at p: CGPoint) {
if lastJump {
//animator.behaviors.count = 4
animator.removeAllBehaviors()
//still, animator.behaviors.count = 4
}
}
最佳答案
你说你这样测试:
public func collisionBehavior(_ behavior: UICollisionBehavior, beganContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, at p: CGPoint) {
if lastJump {
//animator.behaviors.count = 4
animator.removeAllBehaviors()
//still, animator.behaviors.count = 4
}
}
好吧,
animator.removeAllBehaviors()
是一个应该删除行为的命令,但现在不能执行该命令,因为这些行为仍在运行,包括您的代码正处于中间的行为。如果行为真的在那一刻就停止了,我们甚至永远也达不到你的下一行代码!因此,在代码停止运行(也称为运行循环的结束)之前,动画师实际上不会正确地删除行为。
解决此问题的方法是等到代码停止后再调用
removeAllBehaviors()
。您可以使用我的delay
实用程序(https://stackoverflow.com/a/24318861/341994)轻松做到这一点:public func collisionBehavior(_ behavior: UICollisionBehavior, beganContactFor item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, at p: CGPoint) {
if lastJump {
delay(0.1) {
animator.removeAllBehaviors()
}
}
}