Search code examples
iphoneobjective-cuiviewcalayercgcontext

CALayer drawInContext vs addSublayer


How can I use both of these in the same UIView correctly?

I have one custom subclassed CALayer in which I draw a pattern within drawInContext

I have a another in which I set an overlay PNG image as the contents.

I have a third which is just a background.

How do I overlay all 3 of these items?

[self.layer addSublayer:bottomLayer];    // this line is the problem

[squaresLayer drawInContext:viewContext];
[self.layer addSublayer:imgLayer];

The other 2 by themselves draw correctly if I do them in that order. No matter where I try and put bottomLayer, it always prevents squaresLayer from drawing. The reason I need 3 layers is I intend to animate the colors in the background and custom layers. The top layer is just a graphical overlay.


Solution

  • Might as well paste the code in in case anyone is trying to animate stacked CALayers that have their own internal draw routines

    - (void)drawRect:(CGRect)rect {
    
        [imgLayer removeFromSuperlayer];
    
        CGFloat w = [self.blockViewDelegate w];
        CGFloat h = [self.blockViewDelegate h];
    
        CGFloat wb = w/4;
        CGFloat hb = h/4;
    
        CGContextRef viewContext = UIGraphicsGetCurrentContext();
    
        // Layers
    
        [bottomLayer sizes:wb :hb :1];
        bottomLayer.frame = CGRectMake(0, 0, w, h);
        bottomLayer.opaque = NO;
    
        [topLayer sizes:wb :hb :0];
        topLayer.frame = CGRectMake(0, 0, w, h);
        topLayer.opaque = NO;
    
        // Overlay
    
        imgLayer.frame = CGRectMake(0, 0, w, h);
        imgLayer.opaque = NO;
        imgLayer.opacity = 1.0f;
    
        UIImage *overlay = [self.blockViewDelegate image];
        CGImageRef img = overlay.CGImage;
        imgLayer.contents = (id)img;
    
        // Add layers
    
        [bottomLayer drawInContext:viewContext];
        [topLayer drawInContext:viewContext];
        [self.layer addSublayer:imgLayer];
    
    }
    

    blockViewDelegate is where I am storing width, height, and image information, it is the controller for this UIView.

    topLayer and bottomLayer are of a custom UIView subclass which draw some shapes in the view with variable color information. Later on in my animation I just run "setNeedsDisplay" repeatedly with a timer and this routine repeats, the layers re-draw using updated parameters.