I'm trying to use a series of CALayers as sublayers to a view that needs a little more fine grained drawing than usual. I've been using CATiledLayer
before, and I thought using sublayers would be easier, if not equally finicky. I figured I perform a [self.layer addSublayer:sublayer]
, set the delegate of that new sublayer and then I draw all I want in the drawLayer:inContext:
method. But to my great surprise, my app crashes on addSubview:
(without IB) or somewhere higher up the call stack (when using IB).
According to the docs ...
The CALayer reference seems to dictate exactly what I'm doing, yet it crashes every time:
In iOS, if the layer is associated with a UIView object, this property must be set to the view that owns the layer.
But obviously, I'm screwing something up. Thankfully, it's easily reproducible. Can you explain to me how I should be using sublayers with delegate assignments to receive the right drawLayer:inContext:
calls without crashing?
Steps to reproduce
Put this in the class of a custom view put on screen with Interface Builder (or rewrite the init to be called initWithFrame:
):
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
CALayer *sublayer = [CALayer layer];
sublayer.frame = self.layer.bounds;
// Disable or enable this next line to
// resolve or trigger an EXC_BAD_ACCESS crash.
//
sublayer.delegate = self;
[self.layer addSublayer:sublayer];
[self.layer setNeedsDisplay];
}
return self;
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
CGContextSetFillColorWithColor(ctx, [[UIColor greenColor] CGColor]);
CGContextFillRect(ctx, self.bounds);
}
If you run this code, your app will crash. Mind the sublayer.delegate = self
line. If you disable that one, your app will run, but the drawLayer:inContext:
method is never called for that sublayer.
What am I doing wrong?