Adding Transforms to a CALayer (translate, rotate, scale)
There are a number of different transforms you can do on a layer, but the basic ones are
- translate (move)
To do transforms on a
CALayer, you set the layer's
transform property to a
CATransform3D type. For example, to translate a layer, you would do something like this:
Make is used in the name for creating the initial transform: CATransform3DMakeTranslation. Subsequent transforms that are applied omit the
Make. See, for example, this rotation followed by a translation:
Now that we have the basis of how to make a transform, let's look at some examples of how to do each one. First, though, I'll show how I set up the project in case you want to play around with it, too.
For the following examples I set up a Single View Application and added a
UIView with a light blue background to the storyboard. I hooked up the view to the view controller with the following code:
There are many different kinds of
CALayer, but I chose to use
CATextLayer so that the transforms will be more clear visually.
The translation transform moves the layer. The basic syntax is
tx is the change in the x coordinates,
ty is the change in y, and
tz is the change in z.
In iOS the origin of the coordinate system is in the top left, so if we wanted to move the layer 90 points to the right and 50 points down, we would do the following:
- Remember that you can paste this into the
transformExample()method in the project code above.
- Since we are just going to deal with two dimensions here,
tzis set to
- The red line in the image above goes from the center of the original location to the center of the new location. That's because transforms are done in relation to the anchor point and the anchor point by default is in the center of the layer.
The scale transform stretches or squishes the layer. The basic syntax is
sz are the numbers by which to scale (multiply) the x, y, and z coordinates respectively.
If we wanted to half the width and triple the height, we would do the following
- Since we are only working in two dimensions, we just multiply the z coordinates by 1.0 to leave them unaffected.
- The red dot in the image above represents the anchor point. Notice how the scaling is done in relation to the anchor point. That is, everything is either stretched toward or away from the anchor point.
The rotation transform rotates the layer around the anchor point (the center of the layer by default). The basic syntax is
angle is the angle in radians that the layer should be rotated and
z are the axes about which to rotate. Setting an axis to 0 cancels a rotation around that particular axis.
If we wanted to rotate a layer clockwise 30 degrees, we would do the following:
- Since we are working in two dimentions, we only want the xy plane to be rotated around the z axis. Thus we set
- This rotated the layer in a clockwise direction. We could have rotated counterclockwise by setting
- The red dot shows where the anchor point is. The rotation is done around the anchor point.
In order to combine multiple transforms we could use concatination like this
However, we will just do one after another. The first transform will use the
Make in its name. The following transforms will not use
Make, but they will take the previous transform as a parameter.
This time we combine all three of the previous transforms.
- The order that the transforms are done in matters.
- Everything was done in relation to the anchor point (red dot).
A Note about Anchor Point and Position
We did all our transforms above without changing the anchor point. Sometimes it is necessary to change it, though, like if you want to rotate around some other point besides the center. However, this can be a little tricky.
The anchor point and position are both at the same place. The anchor point is expressed as a unit of the layer's coordinate system (default is
0.5, 0.5) and the position is expressed in the superlayer's coordinate system. They can be set like this
If you only set the anchor point without changing the position, then the frame changes so that the position will be in the right spot. Or more precisely, the frame is recalculated based on the new anchor point and old position. This usually gives unexpected results. The following two articles have an excellent discussion of this.
This example originally comes from this Stack Overflow example.
Creating a CALayer
You can create a CALayer and set its frame like this:
You can then add it as a sublayer to an existing CALayer:
To do this you need to include the QuartzCore framework.
Creating particles with CAEmitterLayer
The CAEmitterLayer class provides a particle emitter system for Core Animation. The particles are defined by instances of CAEmitterCell.
The particles are drawn above the layer’s background color and border.
CALayer property animations are enabled by default. When this is undesirable, they can be disabled as follows.
Emitter View with custom image
For example we will create view that contains emitter layer and animates particles.
You need to add "confetti" image or define rect with confetti.contentsRect
How to add a UIImage to a CALayer
You can add an image to a view's
layer simply by using its
- Note that the
UIImageneeds to be converted to a
If you wish to add the image in its own layer, you can do it like this:
Modifying the appearance
The above code produces a view like this. The light blue is the
UIView and the dark blue star is the
As you can see, though, it looks pixelated. This is because the
UIImage is smaller than the
UIView so it is being scaled to fill the view, which is the default it you don't specify anything else.
The examples below show variations on the layer's
contentsGravity property. The code looks like this:
In iOS, you may want to set the
geometryFlipped property to
true if you are doing anything with top or bottom gravity, otherwise it will be the opposite of what you expect. (Only the gravity is flipped vertically, not the content rendering. If you are having trouble with the content being flipped, see this Stack Overflow answer.)
There are two
UIView examples below for every
contentsGravity setting, one view is larger than the
UIImage and the other is smaller. This way you can see the effects of the scaling and gravity.
This is the default.
- Content mode property of a view
- Drawing a
- CALayer Tutorial: Getting Started
- This example comes originally from this Stack Overflow answer.
You can use 5 properties on each layer to configure your shadows:
shadowOffset- this property moves your shadow left/right or up/down
shadowColor- this sets the color of your shadow
shadowOpacity- this is the opacity of the shadow, from
shadowRadius- this is the blur radius (equivalent of the blur property in Sketch or Photoshop)
shadowPath- this is an important property for performance, when unset iOS bases the shadow on the alpha channel of the view, which can be performance intensive with a complex PNG with alpha. This property lets you force a shape for your shadow and be more performant because of it.