We’re all familiar with the geometry of views. Usually we interact with them by setting or getting the frame to have the view appear where we want it on screen. The frame is actually a derived property, stored as the bounds and center of the view. When you set the frame of a view it sets the bounds and the center and when you later ask for the frame it gets calculated from those values.
Layers work almost the same, they have properties for the frame (derived), bounds, position and anchor point. By default the anchor point is in the center of the layer, in which case the position corresponds to the center property of the view. But the anchor point can be moved and then the above statement is no longer true.
The anchor point is defined in the unit coordinate space of the bounds which means that its x and y value both go from 0 to 1 within the bounds of the layer. The x value is 0 at the left edge of the layer and 1 at the right edge and similarly for the y value. Note that the screen coordinate space is different between iOS and OS X. On iOS, y increases downwards while it increases upwards on OS X. So the anchor point (0, 0) is either in the top left or bottom left depending on your platform.
Why is there an anchor point?
All transforms are applied relative to the anchor point, by default it is the center of the layer. Scaling down makes the layer shrink in all directions keeping the same position. Applying a rotation makes the view turn around the center. This is the same behavior as you get when applying an affine transform on a view but layers are more powerful than that. If the anchor point was changed to the lower left corner and the same scale and rotation transforms were applied we would get very different effects.
Layers also support 3D transforms so you could move the anchor point to the edge and apply a rotation around the y axis (hold your open hand straight up and twist it back and forth) to create an effect that looks like an opening door.
But something else is happening…
If you’ve experimented with the anchor point before you may have been confused by one thing. When you change the anchor point, the layer actually moves as well. This is because the anchor point and the position is always the same point, only in different coordinate spaces (the anchor point in the bounds’s unit coordinate space and the position in the super layer’s coordinate space). Since the frame (where the layer appears on screen) is being calculated from the bounds, position and anchor point and only one of them changes then the frame will also have to change.
We can’t have the anchor point move to the corner and the frame stay the same without changing the position so that the frame calculations still are valid. We could calculate and set the correct position ourselves but if we know the frame then we can simply set it and have the correct position (given our anchor point) be calculated for us. Now the layer appears where we want it and the anchor point has moved to the corner.
It may seem strange and stupid that the frame should change if all you wanted was to change the point that the layer transforms relative to. You could argue over whether it makes more sense that the position changes or that the frame changes. You could also argue over whether or not the anchor point should affect the frame calculation at all. Couldn’t the layer have a frame, bounds and center, just like the view so that the anchor point would only be related to the transform? If you stop and think about it for a while the current way starts to make more and more sense.
Say for example that you wanted to make an analog clock inside your app. After having set the anchor point of the hands, setting their position to anything other than the center of the clock-face would simply feel wrong. The hands (in the coordinate space of the clock-face) are anchored in the center, just as they would be in the physical world.
Not only for transforms
As indicated by the clock example above, sometimes the center is not the anchor point you want to use. Have you ever subtracted half the width or height to calculate the position of that layer (or view)? By setting the anchor points to the edge and the positions to the same point you can align multiple layers no matter the size of their content. If the size increases or decreases you can still be sure that the views will stay aligned.
iPhoto for iOS
iPhoto for iOS gives us two beautiful examples of rotation around non-center anchor points. When choosing what kind of effect to apply to an image, the effect controls fan out like a swatch book and on selection they rotate back leaving you with the selected effect control visible at the bottom of the screen.
There is a similar rotation for brushes. By default all brushes lie next to each other on the tool bar and when it comes to selecting a brush they all fan together. A rotation is applied to each brush and all their positions are changed to the same point. This makes them look like a fan. This example is slightly more advanced since it involved more movement (both position and rotation). When selecting a brush the rotation is reversed and each brush gets their own position again so that they end up next to each other.
Thinking outside the box
So far the anchor point has always been within the bounds of the layer but it doesn’t have to. Within the bounds of the layer the values go from 0 to 1.
What would a x-value of 2 mean? Starting from the left edge, 1 is the full width of the layer so a value of 2 would mean 2 full widths of the layer to the right from the left edge. This is the same as 1 full width of the layer to the right from the right edge. Similarly a value of -1 would mean being anchored the full width of the layer to the left of the left edge. As mentioned above, the frame of the layer moves when the anchor point changes so it is quite easy to accidentally move the layer off-screen when using anchor points outside the range of 0 to 1.
All this doesn’t make much sense for positioning, we very rarely want to align things a distance proportional to their size from a point but we sometimes want to transform relative to a points outside our own bounds. Doing a rotation around a points outside the bound without using the anchor point would require calculating the circular path ourselves and using a key-frame animation for the position with that path. For a true rotation we would also have to apply a rotation of the layer (relative to its center). If we instead changed the anchor point we would only rotate and be done with it.
We could also scale a layer relative to an outside point but we would have to keep in mind that everything about the layer scales relative to the anchor point, both the size and the distance. This means that if we scale to twice the size the distance would also double.
The anchor point is animatable
If you read through the documentation you will see that the anchor point is actually animatable. This means that you can have a fixed point in space (if the position doesn’t change) that you can push the layer trough. You could of course do the same thing by animating the position instead (as long as transforms are not involved) but the anchor points allows you to describe the movement relative to the size, e.g. “I want the layer to move from the center all the way to the bottom”.
If you didn’t know of the anchor point before reading this post, I hope that you learned enough to know when to use it.
If you’ve used the anchor point before but felt that its behavior was strange and have avoided using it since, I hope that this post explained some of that behavior and caused you to reconsider.
Finally, if you knew all this, good for you :)