0

How do I draw a layer without a transaction animation? For example, when I set the contents of a layer using CATransaction it works well:

[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
                 forKey:kCATransactionDisableActions];
myLayer.contents = (id)[[imagesTop objectAtIndex:Number]CGImage];
[CATransaction commit];

but I need to change contents from the delegate method [myLayer setNeedsDisplay]. Here is the code:

-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
    CGContextDrawImage(context, rect, Image.CGImage]);    
}
Costique
  • 23,712
  • 4
  • 76
  • 79
Andrew
  • 168
  • 5

2 Answers2

2

CALayer implements setNeedsDisplay method:

Calling this method will cause the receiver to recache its content. This will result in the layer receiving a drawInContext: which may result in the delegate receiving either a displayLayer: or drawLayer:inContext: message.

... and displayIfNeeded:

When this message is received the layer will invoke display if it has been marked as requiring display.

If you wrap [myLayer displayIfNeeded] in a CATransaction, you can turn off implicit animation.

Costique
  • 23,712
  • 4
  • 76
  • 79
  • sorry but i need to force th redraw,not only if needed – Andrew Feb 22 '12 at 17:36
  • 1
    First you mark the layer as needing re-drawing (`[myLayer setNeedsDisplay]`). Then you tell it to redraw if needed (`[myLayer displayIfNeeded]`). Since you've already marked the layer as needing re-drawing, it will redraw immediately. See the documentation for `displayIfNeeded`, quoted above. – Costique Feb 22 '12 at 17:41
1

You can subclass CALayer and override actionForKey:,

- (id <CAAction>) actionForKey: (NSString *) key
{
    if ([key isEqualToString: @"contents"])
        return nil;
    return [super actionForKey: key];
}

This code disables the built-in animation for the contents property.

Alternatively, you can achieve the same effect by implementing the layer's delegate method

- (id <CAAction>) actionForLayer: (CALayer *) layer forKey: (NSString *) key
{
    if (layer == myLayer) {
        if ([key isEqualToString: @"contents"])
            return nil;
        return [[layer class] defaultActionForKey: key];
    }
    return [layer actionForKey: key];
}
Costique
  • 23,712
  • 4
  • 76
  • 79