I’m reading Marcus Zarra and Matt Long’s book Core Animation– it’s written on a framework/library mainly for the Mac OS, but I’m using it to learn about iPhone development. So I’m trying all of the exercises, on the iPhone. There are occasional notes regarding the difference, but here is example chapter 5, “Scale Transform,” rewritten for the iPhone. Enjoy!
Now, the iPhone SDK incorporates tons of Core Animation but there are some elements to the architecture that aren’t obvious: namely, how layers and UIViews interact. The color code also was hard to find, so I’m throwing that in as well. The basic gist I got from this exercise was that UIViews do handle a lot of what layers do in Mac O/S, but referring to them, and integrating with the XCode/InterfaceBuilder environment, is still tricky.
We’re going to create a simple view, with a background color, and a layer with a different border and background color. The end result will be the photo to the left.
First, create your project in XCode: an iPhone windows-based project.
In the method, “application didFinishLaunching…”, allocate and initialize a view like normal:
CGRect frame = CGRectMake(110,160,100,100);
UIView *contentView = [[UIView alloc] initWithFrame:frame];
[contentView setBackgroundColor:[UIColor redColor]];
OK so run and test and you should see a nice red square in the middle.
Next, let’s create a layer. Later on we will associate it with the contentView object.
CALayer *workerlayer = [[CALayer layer] retain];
My understanding is that UIViews inherently contain at least one layer. So you can grab one and start manipulating it right off, and then assign other layers to that UIView object, that is simply a wrapper for the essential layer(s) building block. In this example just created my own, then later on write it back to the view. I go over other layer and view options near the end of this post.
Colors & Layers
Next, I create a few color objects. For iPhone, CALayer requires CGColorRef, not like how UIViews take UIColor objects. So to do this, write
[[UIColor blueColor] CGColor]
If you want to delineate RGBs, you need to setup a color space, color ref:
float comps[4] = {0, 1, 0, 1};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
greenColor = CGColorCreate( colorSpace, comps);
Now I have my green color, I’m going to set it to the layer.
workerlayer.backgroundColor = [[UIColor greenColor] CGColor];
OK so now we have a layer, but we need to set the boundaries, and let’s throw in border color, as they do in the book’s example.
workerlayer.borderColor = [[UIColor blueColor] CGColor];
[workerlayer setBorderWidth:5.0f];
CGRect workerframe = [contentView bounds];
workerframe.origin.x = workerframe.size.width /4;
workerframe.origin.y = workerframe.size.height /4;
workerframe.size.width /= 2;
workerframe.size.height /= 2;
So, now I have manipulated my layer, now how do I assign it back to my programmatically created** custom view?
[[contentView layer] addSublayer:workerlayer];
[window addSubview:contentView];
[window makeKeyAndVisible];
We take our contentView, inherent layer object, and add to it the workerlayer we created. Then, we add the contentView to the window, and finally, make the window visible! In the documentation, the contentView cannot be updated after it’s drawn to screen, so make sure not to add it to the window object until you are done futzing with the workerlayer.
Other ways to do this example (or, how I tested it!):
- You can directly access the view’s layer with
[contentView layer]
. - You can assign it to a layer object with:
CALayer *myLayer = contentView.layer
. Note, if you do the above example iwth this, remove the assignment as a sublayer back to the view, and you will overwrite the inherent layer that draws the large red square. - You can create an array of layers and assign them all to the view object.
* I’m a real fan of their blog, Cocoa is My Girlfriend, and the book Core Animation is heartily recommended. I’m simply updating the examples for iPhone, and my own understanding.
It’s also worthwhile to point out that the variable “kScaleKey” used in the book is simply a constant for the string “scaleExample”. They define it in the code that you can download – from their site. So in your implementation file, after importing the header file, add #define kScaleKey @"scaleExample"
and the examples will make a bit more sense.
** You can create a view in Interface Builder, and add its ivar to the .h and .m files, as an IBOutlet, then manipulate and write to the layer. If you had setup the ivar in the .h file, in this .m file you would write (for this example) in the beginning:
contentView = [[UIView alloc] initWithFrame:frame];
Leaving out the pointer and declaration (since you did it in the .h).
More Reading:
No list would be complete without… Class Reference! CA Layer, UIView, CGColor, to name a few.
Short & sweet- how to create color for iPhones code snippet
Dr. Dobb’s Review on Core Animation Book – where I got the helpful link to download the code!