Question

I am able to create a UIImage from a Core Animation layer using the following code:

- (UIImage*)contentsImage;
{
   UIGraphicsBeginImageContext([self bounds].size);
   [self renderInContext:UIGraphicsGetCurrentContext()];
   UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   return image;
}

This code is in my CALayer derived class. The issue I am running into is that I have two CAShapeLayers that are child layers of my layer that do not get rendered to the resulting image. If I add standard CALayers as children they get rendered fine. The Apple docs say:

Renders the receiver and its sublayers into the specified context.

It also says that it's been available since iPhone OS 2.0. Wondering if there is something I'm missing or if I should file a radar.

Any ideas what might keep the child CAShapeLayers from getting drawn to the image?

Thanks.

Was it helpful?

Solution

The CALayer machinery calls renderInContext to create its bitmapped contents property. But in a CAShapeLayer, the path property is not actually rendered to its contents as seen by this note in the header:

The shape as a whole is composited between the layer's contents and its first sublayer.

It stands to reason that renderInContext won't actually render the CAShapeLayer path onto your context. I haven't actually tried this out for myself however.

OTHER TIPS

Don't know if its relevant to you but there is a note in the CALayer documentation for renderInContext that says :

**Important**: The Mac OS X v10.5 implementation of this method does not
support the entire Core Animation composition model. QCCompositionLayer, 
CAOpenGLLayer, and QTMovieLayer layers are not rendered. Additionally,
layers that use 3D transforms are not rendered, nor are layers that specify 
backgroundFilters, filters, compositingFilter, or a mask values. 
Future versions of Mac OS X may add support for rendering these layers
and properties.

Anyways, I ran into a similar problem when using the UIView drawRect function in conjunction with drawing in an image context. The overall UIView that contained subviews would not draw its subviews if I called drawRect (which makes sense now actually since it says in the documentation if you call drawRect you are responsible for filling that entire area regardless of super and subview implementations). I solved my problem by just called drawRect on all my subviews, passing them their own frames.

So I would suggest maybe switching away from renderInContext and use CALayer's drawInContext instead? You'll need to override the method since it doesn't do anything by default. Your subclasses will also need to move the contexts to their appropriate frames. Also to be safe you might want to check that none of the code you add affects normal rendering of these layers.

I filed a radar on this. I can't see any reason in the docs that it shouldn't work.I will respond back here if/when Apple replies to the radar.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top