Adding Transforms to a CALayer translate rotate scale

suggest change


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’s transform property to a CATransform3D type. For example, to translate a layer, you would do something like this:

myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)

The word 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:

let rotation = CATransform3DMakeRotation(CGFloat(30.0 * M_PI / 180.0), 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)

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:

import UIKit

class ViewController: UIViewController {
    var myLayer = CATextLayer()
    @IBOutlet weak var myView: UIView!
    override func viewDidLoad() {
        // setup the sublayer
        // do the transform
    func addSubLayer() {
        myLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
        myLayer.backgroundColor = UIColor.blueColor().CGColor
        myLayer.string = "Hello"
    //******** Replace this function with the examples below ********

    func transformExample() {
        // add transform code here ...


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

CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)

where 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:

myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)



The scale transform stretches or squishes the layer. The basic syntax is

CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)

where sx, sy, and 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

myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)



The rotation transform rotates the layer around the anchor point (the center of the layer by default). The basic syntax is

CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)

where angle is the angle in radians that the layer should be rotated and x, y, 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:

let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)


Multiple transforms

In order to combine multiple transforms we could use concatination like this

CATransform3DConcat(a: CATransform3D, b: CATransform3D)

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.

let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)

// translate
var transform = CATransform3DMakeTranslation(90, 50, 0)

// rotate
transform = CATransform3DRotate(transform, radians, 0.0, 0.0, 1.0)

// scale
transform = CATransform3DScale(transform, 0.5, 3.0, 1.0)

// apply the transforms
myLayer.transform = transform


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

myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)

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.

See also

This example originally comes from this Stack Overflow example.

Feedback about page:

Optional: your email if you want me to get back to you:

Table Of Contents