Why is implicit animation canceling my CABasicAnimation?

I am trying to move the CALayer several points every time the user does something. I set up the animation to work relatively slowly, but when I set the position of the layer after setting up the animation, the implicit animation seems to grab and execute the animation quickly. This is what my code looks like:

    CGPoint point = CGPointMake(layer.position.x + 30, layer.position.y + 30);
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    animation.fromValue = [NSValue valueWithCGPoint: layer.position];
    animation.toValue = [NSValue valueWithCGPoint: point];
    animation.duration = 4;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    [layer addAnimation:animation forKey:@"position"];
    layer.position = point;

      

I tried to remove the last line layer.position = point

that causes the first animation to work as expected, but then when I try to start the animation a second time, the layer goes back to where the layer was before I started the first animation. the only way I was able to work out is to add a delegate to the animation that implements animationDidStop

and sets the point of the layer after the animation finishes. But looking at many other code examples, this is not required. Is there something I am doing wrong?

+3


source to share


2 answers


You should take a look at WWDC'11 Session 421 - Basic Animation Basics, at 45:21 there is an example similar to yours.



They first set a new value on the layer, create an animation, and then add it to the layer. One thing you should notice is the property fillMode

, it should be kCAFillModeBackwards

.

0


source


You don't need to mess with removedOnCompletion

or fillMode

. The wrong position you see is not due to implicit animation. The only thing you weren't able to do was set the new position of the layer just before starting the animation. Your problem was that you are setting a new position after adding animation. Here's how the functional version would look like in Swift 3:



let newPoint = CGPoint(x: layer.position.x + 30, y: layer.position.y + 30)

let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = NSValue(cgPoint: layer.position)
animation.toValue = NSValue(cgPoint: newPoint)

layer.setValue(NSValue(cgPoint: newPoint), forKeyPath: "position")

layer.add(animation, forKey: nil)

      

0


source







All Articles