Core Animation Replicator Layers

Let’s give a look at replicator layers. These are a special type of Core Animation layers that can be useful to create replicas of a generic layer and animate them all together. Before doing that, let’s review the basic concepts about Core Animation.

Refreshing the concepts: layers

CALayer is a model class in the context of the Model-View-Controller design pattern. This means, surprisedly, that CALayer does not draw anything on the screen. Instead, a CALayer contains the information (and that’s why it’s a model class) of a rectangle rendered on the screen. In iOS and now in Mountain Lion, each view object (a UIView in iOS and a NSView in OS X) has a layer object associated to it. More precisely, each view has a property that allows you to access its layer and we say that the view is layer-backed. You can draw the rectangle using the properties contained in the CALayer object and adding the layer as a sublayer of another layer. In this way, you can create a hierarchy of layers, each with its parent layer and its sublayers. This hierarchy is referred to as layer tree.
Let’s create a new layer and add it to an existing one:

Supposing that you are working in a viewcontroller, the previous lines of code create an aLayer object and add it to the layer associated to the viewcontroller view. But, if you run that code, you will see NOTHING on the screen!!! Well, that’s due to the fact that we did not define any bounds and position for that layer. By default, a layer is created with bounds (0, 0, 0, 0) and position (0, 0), i.e. it has size zero and located to the origin of its super layer. Let’s fix that defining the bounds and the initial position of the layer before adding it to the super layer:

If you run it, you will see nothing again. This time the problem is due to the background color of the layer. By default, a layer is created with a white background color. Let’s fix it this too:

Now, you can finally see your yellow rectangle on the screen.
Let’s play a little bit with the layer properties. Check the CALayer class in the Apple documentation and more precisely, go to the Style Attribute section. There, you find properties as opacity, borderWidth, borderColor, shadowColor, shadowPath, and so on. Try to play with them, just adding a new line to the previous source code. For example, let’s modify the corner radius and the shadow of the layer rectangle:

Once you run the previous source code, you should get this:

An example of CALayer

Read the CALayer class documentation. You can really learn a lot of cool stuffs.
Many people do not know that, besides the basic CALayer class, Apple created an entire family of specialized layers. They are subclasses of the CALayer class: CAEAGLLayer, CAEmitterCell, CAGradientLayer, CAReplicatorLayer, CAScrollLayer, CAShapeLayer, CATextLayer, CATransformLayer. Each of these subclasses was designed for a very specialized task. For example, the CATextLayer class should be used to animate text, because it provides the necessary properties and methods to add easily text, change easily the text color, size and font. Instead, the CAGradientLayer can be used to animate gradients, because it allows you to define easily a linear gradient; and so on. You should learn more about the different layers and, before implementing any animation, you should check which layer is more suitable to your purpose. Since each of these subclasses inherits from the CALayer class, all the methods and properties of this class apply to the specialized layers.

And what about animations?

So, now that we reviewed the basics of the Core Animation layers, let’s try to understand what an animation is.
When you modify one of the (animatable) layer properties, Core Animation computes all the intermediate values between the old property value and the new one. Then, it applies the computed values to the layer during a defined period of time. So, for example, if you have a layer on the screen with opacity of value 1.0 and you change it to 0.0, Core Animation does not change it abruptly, but it computes the intermediate values (according to a defined function) and applies them to the layer in 0.25s (this is the default value for an animation duration). The fact that the value does not change abruptly is due to the implicit animation that every layer gets from Core Animation. So, every time you set a new value of any of the animatable properties of a layer, Core Animation animates the property (you can disable this). This means the transition from the old property value to the new one happens smoothly and Core Animation computes all the intermediate values for you. But what if you want more control on the animations? Well, then you have 2 choices: either you alter the default implicit animation values using the animation transaction (CATransaction); or you need to create an explicit animation. An explicit animation is a way to describe the animation of a property according to your need and to achieve that you need to use classes as CABasicAnimation, CAAnimationGroup, CAKeyframeAnimation and so on. Once you have defined the animation, you add it to the layer and the animation is triggered.
These are really the basic of Core Animation and we will give a look later to all these concept. Today, I want to show you how to create beautiful animations using the replicator layers.

Replicator layers

A replicator layer (CAReplicatorLayer) displays replicas of a sublayer and animate them all together. In other words, a replicator layer creates a specified number of copies of its sublayers, each copy potentially having geometric, temporal and color transformations applied to it. Let’s make a simple example. First of all, let’s create a simple layer that will be the sublayer of the replicator layer:

Nothing new so far, right? I just created a generic CALayer with its bounds, position, background color, round corners, shadow and border. Now, let’s create a replicator layer and set some of its properties:

Here the magic. The instanceCount property defines the number of replicas you want. The instanceDelay defines the delay between each replica. This property makes more sense when you define an animation for the sublayer. Then, the green, blue, red and alpha offsets can be used to define the background color offset between 2 replicas. You can see there, I created the layer1 with a white background color. The replicator layer will take that color and compute the background color for the first replica subtracting 0.03 from the green channel, 0.02 from the red channel, 0.01 from the blue channel and 0.05 from the alpha channel. Then, it will use the resulting color and subtract again these numbers to obtain the color for the second replica, and so on. Here, it is assumed that the value for each color channel is in the range between 0 and 1. The last line represents the transform you apply to each replica. The preservesDepth property is used to ensure that the replicator layer does not flatten the sublayers (by default this property is NO).
The last thing you have to do is to add the layer to the replicator layer:

And finally, you have to add the replicator layer to the the layer tree. Here it is the result:

An example of CAReplicatorLayer

Let’s make a much more complex example and take out the power of this kind of layers. Here, what I want to achieve:

Really cool, right? Ok, let’s see how to do it.
Create a new Xcode project and choose the SingleView template. Use ARC. Name the project ReplicatorLayer. Add the QuartzCore framework to the project and in the ViewController.h add:

I created some Core Animation methods that we need to add to the sublayer and to the replicator layer. Add these three animation methods to the view controller class:

Then, let’s write the important part. Add a viewDidAppear method to the view controller and add this piece of code:

As you can see, I created 3 replicator layers. I need this to be able to replicate the sublayer along the x, the y and the z direction. Without any animation, you should get something like this:

An example of a group of layers

I hope you can see that these are layers in a 3D space. The 3 replicator layers replicated the layer on the top-left along the X direction (from left to right), then along the Y direction (from top to bottom) and finally, along the Z direction (from outside to inside the screen).
Now, the first lines of the previous block of code are used to make sure that the set of layers is displayed in the center of the view controller view:

The constants are defined so:

You can change these values and see what happens. I am attaching here the code, so that you can see how to implement it. You need Xcode 4.1.1.

If you liked this post, check here our iOS 6 ready training classes. You can learn more about these and other really advanced topics.

Keep coding,
Geppy

iOS Consulting | INVASIVECODE

iOS Training | INVASIVECODE

(Visited 65 times, 1 visits today)