Graphics Reference
In-Depth Information
If you want to simply zoom the layer
contents
image, you can do so using the layer's
transform
or
affineTransform
properties (see Chapter 5, “Transforms,” for an
explanation of transforms), but that's not the purpose of
contentsScale
.
The
contentsScale
property is actually part of the mechanism by which support for
high-resolution (a.k.a.
Hi-DPI
or
Retina
) screens is implemented. It is used to determine the
size of the backing image that the layer should automatically create when drawing, and the
scale at which the
contents
image should be displayed (assuming that it isn't already
being scaled by the
contentsGravity
setting).
UIView
has an equivalent-but-little-
used property called
contentScaleFactor
.
If
contentsScale
is set to 1.0, drawing will be done at a resolution of 1 pixel per point.
If it is set to 2.0, drawing will be done at 2 pixels per point, a.k.a. Retina resolution. (In case
you are unclear on the distinction between pixels and points, this is explained later in the
chapter.)
This doesn't actually make any difference when using
kCAGravityResizeAspect
because it scales the image to fit the layer, regardless of its resolution. But if we switch our
contentsGravity
to
kCAGravityCenter
instead (which doesn't scale the image),
the difference will be more apparent (see Figure 2.3).
Figure 2.3
A Retina image displayed with the wrong
contentsScale
by default
As you can see, our snowman is huge and pixelated. That's because
CGImage
(unlike
UIImage
) has no internal concept of scale. When we used the
UIImage
class to load our
snowman image, it correctly loaded the high-quality Retina version. But when we used the
CGImage
representation to set that image as our layer
contents
, the scale factor was
lost in translation. We can fix that by manually setting the
contentsScale
to match our
UIImage
scale
property (see Listing 2.2). Figure 2.4 shows the result.