tl;dr: You need to manually add each animation after the previous finishes.
There is no built in way to add sequential animations. You could set the delay of each animation to be the sum of all previous animations but I wouldn't recommend it.
Instead I would create all the animations and add them to a mutable array (using the array as a queue) in the order they are supposed to run. Then by setting yourself as the animations delegate to all the animations you can get the animationDidStop:finished:
callback whenever an animation finishes.
In that method you will remove the first animation (meaning the next animation) from the array and add it to the layer. Since you are the delegate you will get a second animation when that one finishes in which case the animationDidStop:finished:
callback will run again and the next animation is removed from the mutable array and added to the layer.
Once the array of animations is empty, all animations will have run.
Some sample code to get you started. First you set up all your animations:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
[animation setToValue:(id)[[UIColor redColor] CGColor]];
[animation setDuration:1.5];
[animation setDelegate:self];
[animation setValue:[view layer] forKey:@"layerToApplyAnimationTo"];
// Configure other animations the same way ...
[self setSequenceOfAnimations:[NSMutableArray arrayWithArray: @[ animation, animation1, animation2, animation3, animation4, animation5 ] ]];
// Start the chain of animations by adding the "next" (the first) animation
[self applyNextAnimation];
Then in the delegate callback you simply apply the next animation again
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished {
[self applyNextAnimation];
}
- (void)applyNextAnimation {
// Finish when there are no more animations to run
if ([[self sequenceOfAnimations] count] == 0) return;
// Get the next animation and remove it from the "queue"
CAPropertyAnimation * nextAnimation = [[self sequenceOfAnimations] objectAtIndex:0];
[[self sequenceOfAnimations] removeObjectAtIndex:0];
// Get the layer and apply the animation
CALayer *layerToAnimate = [nextAnimation valueForKey:@"layerToApplyAnimationTo"];
[layerToAnimate addAnimation:nextAnimation forKey:nil];
}
I'm using a custom key layerToApplyAnimationTo
so that each animation knows its layer (it works just by setValue:forKey:
and valueForKey:
).