I know that you said that you're using CAKeyframeAnimations, but if you want simple animation of UIView properties (origin, bounds, alpha, etc.), you can wrap the change of the property or properties in a begin / commit block and specify a delegate method that is called upon completion of the animation. As long as the delegate method takes three arguments, you can call it whatever you want. For example:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:ANIMATIONDURATIONINSECONDS];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(yourAnimationHasFinished:finished:context:)];
// Change property or properties here
[UIView commitAnimations];
will cause the method
- (void)yourAnimationHasFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context;
to be called. The arbitrary naming this allows would provide you with a means of separating handling for the completion of different animations. I prefer this for simple animations.
For dealing with more complex animations that interact directly with CALayers, the animationDidStop:finished: delegate method does return the animation object that has finished. If you are making one instance that is the delegate for multiple animations, you could create an NSMutableDictionary of animations and NSNumbers for use in a switch statement within the animationDidStop:finished: method. As you create the CAKeyframeAnimation, use setObject:forKey: to assign it to its matching number, then use objectForKey: to find the number that corresponds to that animation in the completion method and feed that into a switch statement.