- The Simplest Animations
- The Animation Proxy Object
- The Differences Between Window, View, and Layer Animation
- Preparing a View to Perform Layer Animation
- Using CABasicAnimation
- Useful Animation Properties
- Animation Grouping
- Summary
Preparing a View to Perform Layer Animation
The first thing you want to do when you create a Core Animation based project is to make sure the root layer of your view is layer backed. Let's walk through creating a Core Animation-based project and set up the root layer on OS X.
Create the Xcode Project
To create our application, follow these steps:
- In Xcode, press and select Cocoa Application in the Project Templates dialog.
- Name the project CA Basics and click Save.
- Expand the Frameworks group, Control-click the Linked Frameworks subgroup, and select Add > Existing Frameworks.
- In the resulting dialog, navigate to /System/Library/Frameworks and select QuartzCore.framework. Click Add twice, as prompted.
- Control-click the Classes group and select Add > New File.
- In the New File template dialog, select Objective-C class under the Cocoa group and click Next.
- Name the file AppDelegate.m and make sure Also Create "AppDelegate.h" is checked; click Finish.
- Select AppDelegate.h to open the file in the code editor and add the following code:
@interface AppDelegate : NSObject { IBOutlet NSWindow *window; }
- Select AppDelegate.m to open the file in the code editor and add the following code:
@implementation AppDelegate - (void)awakeFromNib; { [[window contentView] setWantsLayer:YES]; } @end
- Under the Resources group in your project, double-click MainMenu.xib to open the XIB in Interface Builder.
- From the Library palette in Interface Builder, drag an NSObject object into MainMenu.xib and rename it to AppDelegate.
- Make sure the AppDelegate object is selected. In the object inspector, click the Identity tab and change the Class field to AppDelegate.
- In the MainMenu.xib, Control-click on File's Owner and drag the connection to the AppDelegate object. Select delegate in ensuing context menu.
- In the MainMenu.xib, Control-click on AppDelegate and drag the connection to the Window object. Select window in the ensuing context menu.
- Save the xib file and return to Xcode.
The project is now set up. In the preceding steps, we created an application delegate that we use to provide control to our layer, window, and view.
Add the Animation Layer to the Root Layer
To add a layer that we will be animating, do the following:
- Open AppDelegate.h and add a CALayer instance variable:
@interface AppDelegate : NSObject { IBOutlet NSWindow *window; CALayer *layer; }
- Open AppDelegate.m and add the layer initialization code in -awakeFromNib:
@implementation AppDelegate - (void)awakeFromNib; { [[window contentView] setWantsLayer:YES]; layer = [CALayer layer]; [layer setBounds:CGRectMake(0.0, 0.0, 100.0, 100.0)]; // Center the animation layer [layer setPosition:CGPointMake([[window contentView] frame].size.width/2, [[window contentView] frame].size.height/2)]; CGColorRef color = CGColorCreateGenericRGB(0.4, 0.3, 0.2, 1); [layer setBackgroundColor:color]; CFRelease(color); [layer setOpacity:0.75]; [layer setBorderWidth:5.0f]; [[[window contentView] layer] addSublayer:layer]; } @end
Layer Allocation Considerations
Another consideration of which you should be aware when you set up your layers is that even though you have an instance variable (ivar) of your CALayer, it is not retained unless you explicitly retain it. In the world of memory management in Objective-C, the rule of thumb is that you retain only that which you need to retain. You should not retain objects you don't need to hold onto, and you should retain objects that you do need. It sounds simple, but in practice it tends to be more elusive. In our code in the previous steps, you see we allocate our layer by using the convenience initializer layer = [CALayer layer];. This allocates an auto-released CALayer object. When the layer object goes out of scope in the –awakeFromNib, it will be auto-released unless it is retained. In our case, we are adding it to the contentView layer sublayers array, which is retaining the layer for us. If, however, we wanted to wait until later to actually add the layer that we initialized in –awakeFromNib to the sublayers array, we need to allocate the layer by using layer = [[CALayer alloc] init]. Then we need to release the layer in the dealloc method with a call to [layer release];.
The first time you go to use the CALayer method called –removeFromSuperlayer, you will find that if you try to add the layer to the sublayer array again, it will crash your application. This is because the layer will be released in the call to –removeFromSuperlayer. You must retain the layer yourself if you want to remove it from its superlayer but keep it around in memory.