The animation itself is fairly useless. It just animates our company logo, fading in, moving diagonally across the screen, rotating, falling (with an slide whistle sound), rotating back to it's original orientation, sliding sideways back to it's starting position, and then fading out again.
You can download the project at this link: iOS Core Animation project
Description:
The core of the program is a routine called -doAnimation that triggers the animation sequence.
It creates a whole bunch of CABasicAnimation objects, each with a start time that is after the end of the previous animation. It then creates a CAAnimationGroup object and installs all the individual animations into that group. Its sets the duration of the animation group to the total time for all the component animations.
I created a variable that keeps track of the total time for all the animations so far, so it can figure out when to start the next animation in the sequence.
The animations are installed on the layer that backs the image view I am animating.
In order for each animation to build on the previous animation, you have to set fillMode = kCAFillModeForwards and removedOnCompletion = FALSE (which leaves the animation's effects in force once it's finished.) You have to do those steps for every animation in the group AND for the group animation. I tried setting removedOnCompletion to TRUE for one of the animations in the group, and it behaves very strangely.
I wanted to add a sound to the mix at a specific point in the animation sequence. Normally, with CABasicAnimation, you can set an object up as a delegate of the animation, and if it finds a animationDidStop:finished: method in the delegate, it will call it once that animation is complete. Apparently that doesn't work when an animation is part of a group. I think the reason is that the animationDidStop method is called "when the animation completes its active duration or is removed from the object it is attached to." In this case, the animation is part of a group, so it doesn't get removed from the group it belongs to.
The docs say that animations don't actually change the underlying properties that they animate (location, frame, opacity, transform, etc.) but only create the appearance of that property being changed. They instruct you to change the underlying value through code after submitting the animation if you want the layer to keep the changes applied by the animation. However, there's a gotcha. CAAnimations are added to layers, not view objects. By default, layers do an implicit animation when you change one of their values. Simply executing the statement
layer.opacity = 0.0;
Causes the layer to fade away. You have to use a block of code like this if you want a change to a layer setting not to animate:
[CATransaction begin];
[CATransaction setValue: [NSNumber numberWithBool: YES]
forKey: kCATransactionDisableActions];
imageOne.layer.opacity = 0.0;
[CATransaction commit];
[CATransaction setValue: [NSNumber numberWithBool: YES]
forKey: kCATransactionDisableActions];
imageOne.layer.opacity = 0.0;
[CATransaction commit];
One of the Core Animation books I'm reading says that you can actually use a CAAnimation object to animate properties in other objects than just the target for the animation. The only requirement is that you be able to build a key KVO expression that links to the target object (e.g. "parentView.sprite1View.legView.layer.position"). I'll