Reputation: 1474
I'm trying to implement an animation to move a view to the position I tap. Each tap would cancel the previous animation and start moving again from the current position.
class MoveAnimationViewController: UIViewController {
lazy var block: UIView = {
let block = UIView()
block.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
block.backgroundColor = UIColor.greenColor()
return block
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(block)
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "tap:"))
}
func tap(gesture: UITapGestureRecognizer) {
let fromPosition = (block.layer.presentationLayer() ?? block.layer).position
let toPostion = gesture.locationInView(view)
block.layer.removeAllAnimations()
let animation = CABasicAnimation(keyPath: "position")
animation.duration = 2
animation.fromValue = NSValue(CGPoint: fromPosition)
animation.toValue = NSValue(CGPoint: toPostion)
block.layer.addAnimation(animation, forKey: nil)
block.layer.position = toPostion
}
}
However, the block view jumps to the destination directly without any animation.
Replace the following code
block.layer.addAnimation(animation, forKey: nil)
with
block.layer.addAnimation(animation, forKey: "move")
will fix the problem, but why?
By the way, the following statement looks illegal, since the presentationLayer
method returns a AnyObject?
, which has no position
property. Right?
let fromPosition = (block.layer.presentationLayer() ?? block.layer).position
It should be replaced with this, I guess. But the compiler doesn't warn me. Is it a bug?
let fromPosition = (block.layer.presentationLayer() as? CALayer ?? block.layer).position
Upvotes: 0
Views: 1124
Reputation: 41246
If you name an animation, i.e. associate a key with it, then it will replace any other animations with the same key. If you give it no name that automatic cancel and replace doesn't happen.
Upvotes: 2