Before writing this question, I've
- had experience with Affine transforms for views
- read the Transforms documentation in the Quartz 2D Programming Guide
- seen this detailed CALayer tutorial
- downloaded and run the LayerPlayer project from Github
However, I'm still having trouble understanding how to do basic transforms on a layer. Finding explanations and simple examples for translate, rotate and scale has been difficult.
Today I finally decided to sit down, make a test project, and figure them out. My answer is below.
Notes:
- I only do Swift, but if someone else wants to add the Objective-C code, be my guest.
- At this point I am only concerned with understanding 2D transforms.
Basics
There are a number of different transforms you can do on a layer, but the basic ones are
To do transforms on a
CALayer
, you set the layer'stransform
property to aCATransform3D
type. For example, to translate a layer, you would do something like this:The word
Make
is used in the name for creating the initial transform: CATransform3DMakeTranslation. Subsequent transforms that are applied omit theMake
. 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.
Setup
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 useCATextLayer
so that the transforms will be more clear visually.Translate
The translation transform moves the layer. The basic syntax is
where
tx
is the change in the x coordinates,ty
is the change in y, andtz
is the change in z.Example
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:
Notes
transformExample()
method in the project code above.tz
is set to0
.Scale
The scale transform stretches or squishes the layer. The basic syntax is
where
sx
,sy
, andsz
are the numbers by which to scale (multiply) the x, y, and z coordinates respectively.Example
If we wanted to half the width and triple the height, we would do the following
Notes
Rotate
The rotation transform rotates the layer around the anchor point (the center of the layer by default). The basic syntax is
where
angle
is the angle in radians that the layer should be rotated andx
,y
, andz
are the axes about which to rotate. Setting an axis to 0 cancels a rotation around that particular axis.Example
If we wanted to rotate a layer clockwise 30 degrees, we would do the following:
Notes
x
andy
to0.0
and setz
to1.0
.z
to-1.0
.Multiple transforms
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 useMake
, but they will take the previous transform as a parameter.Example
This time we combine all three of the previous transforms.
Notes
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 thisIf 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.
See also
CALayer