How to specify selector when CAKeyframeAnimation is finished?
Asked Answered
B

3

22

I'm using a CAKeyframeAnimation to animate a view along a CGPath. When the animation is done, I'd like to be able to call some other method to perform another action. Is there a good way to do this?

I've looked at using UIView's setAnimationDidStopSelector:, however from the docs this looks like it only applies when used within a UIView animation block (beginAnimations and commitAnimations). I also gave it a try just in case, but it doesn't seem to work.

Here's some sample code (this is within a custom UIView sub-class method):

// These have no effect since they're not in a UIView Animation Block
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];    

// Set up path movement
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"path"];
pathAnimation.calculationMode = kCAAnimationPaced;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.duration = 1.0f;

CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.center.x, self.center.y);

// add all points to the path
for (NSValue* value in myPoints) {
    CGPoint nextPoint = [value CGPointValue];
    CGPathAddLineToPoint(path, NULL, nextPoint.x, nextPoint.y);
}

pathAnimation.path = path;
CGPathRelease(path);

[self.layer addAnimation:pathAnimation forKey:@"pathAnimation"];

A workaround I was considering that should work, but doesn't seem like the best way, is to use NSObject's performSelector:withObject:afterDelay:. As long as I set the delay equal to the duration of the animation, then it should be fine.

Is there a better way? Thanks!

Blowfly answered 18/3, 2010 at 7:37 Comment(0)
E
25

CAKeyframeAnimation is a subclass of CAAnimation. There is a delegate property in CAAnimation. The delegate can implement the -animationDidStop:finished: method. The rest should be easy.

Eklund answered 18/3, 2010 at 7:46 Comment(2)
Sweet, thanks! I must have missed that when looking over the docs.Blowfly
This is why you shouldn't link and write the answer here. All links are broken!Heavyweight
J
39

Or you can enclose your animation with:

[CATransaction begin];
[CATransaction setCompletionBlock:^{
                   /* what to do next */
               }];
/* your animation code */
[CATransaction commit];

And set the completion block to handle what you need to do.

Jackstraw answered 19/6, 2012 at 9:39 Comment(0)
E
25

CAKeyframeAnimation is a subclass of CAAnimation. There is a delegate property in CAAnimation. The delegate can implement the -animationDidStop:finished: method. The rest should be easy.

Eklund answered 18/3, 2010 at 7:46 Comment(2)
Sweet, thanks! I must have missed that when looking over the docs.Blowfly
This is why you shouldn't link and write the answer here. All links are broken!Heavyweight
I
7

Swift 3 syntax for this answer.

CATransaction.begin()
CATransaction.setCompletionBlock {
    //Actions to be done after animation
}
//Animation Code
CATransaction.commit()
Inset answered 24/1, 2017 at 10:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.