Ken Zhang
Ken Zhang

Reputation: 1474

iOS: Why does the key of animation matter?

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

Answers (1)

David Berry
David Berry

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

Related Questions