Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CALayers never calls it's delegate's drawLayer:inContext: even after [layer setNeedsDisplay] and [layer display]

I can't figure out why the CALayer's I'm creating are not calling their drawLayer method. I've created a drawLayer delegate object for them, yet it never gets called. From a UIView subclass:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

       UIView *bg = [[UIView alloc] initWithFrame:self.bounds];
       // I have a property called 'bg' to reference the child UIView
       self.bg = bg;
       [self addSubview:self.bg];

       // an NSObject subclass I use as a CALayer delegate
       MyLayerDelegate *drawer = [MyLayerDelegate new];
       self.drawer = drawer;


       CAGradientLayer *layer = [CAGradientLayer layer];;
       layer.delegate = self.drawer;
       layer.name = @"bg";

       [self.bg.layer addSublayer:layer];

       [layer setNeedsDisplay];
       [layer display];

    }
    return self;
}

In self.drawer I have:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
    NSLog(@"layer called drawLayer");
    // Some drawing goes here
}

I've tried many different things. I've tried setting setNeedsDisplay on self.bg.layer, I've tried setNeedsDisplay on self.bg, I've tried [layer setNeedsDisplay] before AND after addSublayer, I've tried [layer display] before and after addSublayer. I've tried with and without [layer display] and [layer displayIfNeeded].

Why does the layer refuse to draw?

like image 219
zakdances Avatar asked Apr 13 '13 13:04

zakdances


1 Answers

The layer frame needs to be non-zero. This solved the problem:

layer.frame = self.bg.bounds;
[layer setNeedsDisplay];
[self.bg.layer addSublayer:layer];
like image 94
zakdances Avatar answered Nov 06 '22 02:11

zakdances