Home > Articles

  • Print
  • + Share This
This chapter is from the book

Working with Layers

Let’s start by creating a simple project that will allow us to manipulate the properties of a layer. In Xcode, create a new iOS project using the Single View Application template.

Create a small view (around 200×200 points) in the middle of the screen. You can do this either programmatically or using Interface Builder (whichever you are more comfortable with). Just make sure that you include a property in your view controller so that you can access the small view directly. We’ll call it layerView.

If you run the project, you should see a white square in the middle of a light gray background (see Figure 1.3). If you don’t see that, you may need to tweak the background colors of the window/view.

Figure 1.3

Figure 1.3. A white UIView on a gray background

We could achieve this effect by simply using another UIView and adding it as a subview to the one we’ve already created (either in code or with Interface Builder), but that wouldn’t really teach us anything about layers.

Instead, let’s create a CALayer and add it as a sublayer to the backing layer of our view. Although the layer property is exposed in the UIView class interface, the standard Xcode project templates for iOS apps do not include the Core Animation headers, so we cannot call any methods or access any properties of the layer until we add the appropriate framework to the project. To do that, first add the QuartzCore framework in the application target’s Build Phases tab (see Figure 1.4), and then import <QuartzCore/QuartzCore.h> in the view controller’s .m file.

Figure 1.4

Figure 1.4. Adding the QuartzCore framework to the project

After doing that, we can directly reference CALayer and its properties and methods in our code. In Listing 1.1, we create a new CALayer programmatically, set its backgroundColor property, and then add it as a sublayer to the layerView backing layer. (The code assumes that we created the view using Interface Builder and that we have already linked up the layerView outlet.) Figure 1.5 shows the result.

Figure 1.5

Figure 1.5. A small blue CALayer nested inside a white UIView

The CALayer backgroundColor property is of type CGColorRef, not UIColor like the UIView class’s backgroundColor, so we need to use the CGColor property of our UIColor object when setting the color. You can create a CGColor directly using Core Graphics methods if you prefer, but using UIColor saves you from having to manually release the color when you no longer need it.

Listing 1.1. Adding a Blue Sublayer to the View

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *layerView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //create sublayer
    CALayer *blueLayer = [CALayer layer];
    blueLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
    blueLayer.backgroundColor = [UIColor blueColor].CGColor;

    //add it to our view
    [self.layerView.layer addSublayer:blueLayer];
}

@end

A view has only one backing layer (created automatically) but can host an unlimited number of additional layers. As Listing 1.1 shows, you can explicitly create standalone layers and add them directly as sublayers of the backing layer of a view. Although it is possible to add layers in this way, more often than not you will simply work with views and their backing layers and won’t need to manually create additional hosted layers.

On Mac OS, prior to version 10.8, a significant performance penalty was involved in using hierarchies of layer-backed views instead of standalone CALayer trees hosted inside a single view. But the lightweight UIView class in iOS barely has any negative impact on performance when working with layers. (In Mac OS 10.8, the performance of NSView is greatly improved, as well.)

The benefit of using a layer-backed view instead of a hosted CALayer is that while you still get access to all the low-level CALayer features, you don’t lose out on the high-level APIs (such as autoresizing, autolayout, and event handling) provided by the UIView class.

You might still want to use a hosted CALayer instead of a layer-backed UIView in a real-world application for a few reasons, however:

  • You might be writing cross-platform code that will also need to work on a Mac.
  • You might be working with multiple CALayer subclasses (see Chapter 6, “Specialized Layers”) and have no desire to create new UIView subclasses to host them all.
  • You might be doing such performance-critical work that even the negligible overhead of maintaining the extra UIView object makes a measurable difference (although in that case, you’ll probably want to use something like OpenGL for your drawing anyway).

But these cases are rare, and in general, layer-backed views are a lot easier to work with than hosted layers.

  • + Share This
  • 🔖 Save To Your Account