Let’s continue with this tutorial on Core Animation. It’s time to go with the keyframe animations.

Keyframe animations are represented by the class CAKeyframeAnimation. They provide you with more precise control on your animations. While for a basic animation (CABasicAnimation) you just define a starting and an ending value for an animatable property and Core Animations calculates the intermediate values, the keyframe animations allow you to provide the values between the beginning and the end of the animation.

CAKeyframeAnimation asks you need to define 2 arrays: one containing the sequence of the animatable property values and another one defining the instants of time. So, the first array contains the sequence of the values of the animatable property. The second array contains the sequence of the time frames of the total animation duration. The 2 arrays must have the same length, so that each element of the value array corresponds to an element of the time array.

Let’s give a look at a simple example. Suppose I use the same layer of the previous posts:

This time, I want to move the layer from a position to another one in just 2 seconds, then move it to a third position in just 1 second and, finally, move it to a fourth position in 3 seconds. Let’s create the time array, first. The total duration of the animation will be 6s (= 2s+1s+3s). The first part of the animation will last 33% (= 2s/6s * 100) of the animation. The second part of the animation will take the portion of the duration that goes from the 33% until the 50% (= (2s + 1s) / 6s * 100). Finally, the third part will take the portion of the total duration that goes between the 50% and the 100%. The time is expressed in percentage (in reality in rates), so that you don’t need to recalculate them incase you modify the animation duration.

Let’s now create a key frame animation:

We pass the times using the -keyTimes property of the CAKeyframeAnimation class:

Now, we need to define the values for each key time. The sequence of points representing the layer position will be

(100.0, 100.0) -> (100.0, 200.0) -> (220.0, 200.0) -> (220.0, 100.0)

As you know, points can be defined using the CGPoint type. We need to encapsulate this type in an object and be able to pass them to an NSArray. Apple added for us a new category of the NSValue class as an addition to UIKit. Look for NSValue UIKit Additions Reference and you will find the class method +valueWithCGPoint:. This method takes a CGPoint and create an NSValue object out of it. So, our array of values can be created in this way:

and passed to the animation:

We need now to define the animation duration:

and start the animation

Don’t forget to add the QuartzCore framework to your project.
I am attaching here the sample project.