First of all, im finding the iPhone online docs to be not-so-very thoroughly clear when it comes to the various ways of rendering a layer. I get the jist of it, but im not clear when to use which methods and which requires the layer to be added as a sub layer or not.
My project started off trivially with me loading images and simply drawing them to a UIView via [image drawAtPoint:] as well as [image drawInRect:]. These work fine using the current graphics context.
Then today i happened to read this concept of using layers so that animating my various images (implicitly) would in theory be a breeze!
For the record, i know the docs say subclassing CALayer is unecessary, but i did just that. Now I am incredibly confused about the different ways to supposedly render a layer.
Now for all of these methods, is it required to set the layer's frame size? Is it required to add a layer to a view's layer?
The only method that gives me visible results is the drawinContext method. But if i apply an implicit animation (e.g. image.opacity = 0) nothing happens, which makes me believe my layer is not properly set up.
Some one please bring order back to this chaos.
Core Animation does make this sort of thing trivial. Brad's suggestion is right on. The bottom line is that you don't need any of those methods to simply render the layer. In order to cause the layer to render, make sure you've done the following:
Set the contents property with:
[imageLayer setContents:(id)[[UIImage imageNamed@"image.png"] CGImage]];
Set the bounds of the layer to the size you want.
[imageLayer setBounds:CGRectMake(0.0f, 0.0f, 50.0f, 50.0f)];
Set the position (x,y location) of the layer to display in the view. The default anchorPoint is the center of the layer. This code centers the layer in your view.
[imageLayer setPosition:CGPointMake([view bounds].size.width/2, [view bounds].size.height/2)];
Add the layer to your view's layer:
[[[self view] layer] addSublayer:imageLayer];
Incidentally, if you prefer, you can set both bounds and position in one method by calling -setFrame:. I prefer to use the two calls myself as it feels more readable to me, but that's up to your own preference. If you do not set the bounds and position or frame of the layer, however, the layer will not render.
If you would prefer, you can avoid using drawInContext by creating additional layers that draw paths, shapes (see CAShaperLayer), or additional images and add them as sublayers of your image layer or add them as sublayers of your parent layer and give them a zPosition that causes them to display in front of your image layer.
Now, if you want to animate the opacity, you can use implicit animation by simply setting the layer property in the exact manner you described, e.g. [imageLayer setOpacity:0.0f]; This will fade the layer and all of it's child layers over 0.25 seconds.
Just some additional thoughts.
Best Regards.
If all that you want your various layers to do is display one image each, you shouldn't need to subclass them at all. You should just be able to set an image (in CGImageRef form) to the contents
property of each layer. The layer will then handle the drawing of that image. You can obtain the Core Graphics image representation of a UIImage using its CGImage
read-only property.
You are correct, though, about -drawInContext:
being the right place to put more custom drawing code within a CALayer subclass. Without subclassing CALayer, you can have a delegate change the layer's drawing behavior through the -drawLayer:inContext:
delegate method.
This is all described in detail within the "Providing Layer Content" section of Apple's Core Animation Programming Guide.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With