CAKeyframeAnimation not changing position as expected

167 views Asked by At

I want to add an entrance animation to my UIView layer that left-shifts + fades-in with a slight bounce at the end. I assign a values array to animation.values, but when the animation runs, it seems to always skip the third value.

It appears as a left shift then right shift, instead of the desired left, right, left shift for the bounce effect.

Here is the code so far:

 CAKeyframeAnimation *leftShift = [CAKeyframeAnimation animationWithKeyPath:@"position.x"];
leftShift.duration = 0.5;
NSArray *viewPositionValues = @[
    @(myView.layer.position.x),
    @(myView.layer.position.x - 22),
    @(myView.layer.position.x - 18),
    @(myView.layer.position.x - 20)
];
leftShift.values = viewPositionValues;
leftShift.keyTimes = @[ @0, @.5, @.75, @1];
myView.center = CGPointMake(myView.layer.position.x - 20, myView.layer.position.y);

CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.fromValue = @0;
myView.layer.opacity = 1;
opacityAnimation.duration = 0.25;

CAAnimationGroup *entranceAnimation = [CAAnimationGroup new];
entranceAnimation.animations = @[ leftShift, opacityAnimation ];
entranceAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
entranceAnimation.fillMode = kCAFillModeForwards;
[CATransaction begin];
[CATransaction setCompletionBlock:completion];
[myView.layer addAnimation:entranceAnimation forKey:kSpeedMenuEntranceAnimationKey];
_speedMenuView.hidden = NO;
[CATransaction commit];

**Edit: Interestingly, adding timing functions for each transition between timestamps specified in leftShift.keyTimes solved this issue.

1

There are 1 answers

0
matt On

The problem is that you have not given your animation group a duration. Therefore it has the default 0.25 second duration, and that is not long enough for the keyframe animation duration of 0.5 to play out in full.

So giving the animation group a sufficiently long duration will solve the problem of not seeing whole keyframe animation. On the other hand I would recommend that you go about this a completely different way and use UIKit dynamics or a springing animation to achieve the standard bounce effect, rather than trying to "build" a bounce from scratch, as it were.