0

[CALayerDelegate displayLayer:] is described here.

[NSView updateLayer] is described here.

How do they differ? When would I use one over the other?

Lucas Derraugh
  • 6,929
  • 3
  • 27
  • 43
aleclarson
  • 18,087
  • 14
  • 64
  • 91

2 Answers2

2

-[NSView updateLayer:]

The purpose of this method is to be overridden by an NSView subclass so that you can customize the backing layer. By default, -[NSView drawRect:] will be used and you're not supposed to manipulate the backing layer directly (like you might with UIView on iOS). If you want to customize the backing layer, you're supposed to use -updateLayer and perform your customizations in this method. To opt into using updateLayer rather than drawRect:, you override -[NSView wantsUpdateLayer] and return YES. Now you can change any property on the backing layer inside of -updateLayer. To notify the view that a change needs to occur you would use the needsDisplay property and set it to YES, which will trigger -updateLayer when it does a render pass. It's also good to know about the layerContentsRedrawPolicy property that controls when a redraw is triggered.

Example usage:

@implementation MyView

- (BOOL)wantsUpdateLayer {
    return YES;
}

- (void)updateLayer {
    // Perform different customizations based on view/control state.
    self.layer.backgroundColor = NSColor.redColor.CGColor;
    self.layer.contents = <some image>;
}

@end

// Example of notifying MyView instance that it needs to update itself
myView.needsDisplay = YES;

Shameless plug of a video I did on this topic somewhat recently.

-[CALayerDelegate displayLayer:]

This call is specific to CALayer. If you aren't dealing with NSView, then this is how you can be notified of CALayer needing a change as a result of calling -[CALayer setNeedsDisplay].

In short, if you're dealing with NSView and want to have full control over the backing layer, you must override -wantsUpdateLayer to return YES and implement -updateLayer. If you're directly using CALayers (no NSView involved), then the delegate can be useful here.

Community
  • 1
  • 1
Lucas Derraugh
  • 6,929
  • 3
  • 27
  • 43
  • To clarify, I was asking about the `displayLayer:` method of `CALayerDelegate`, not `CALayer` – aleclarson Jan 16 '20 at 07:38
  • Oh, I see you mention the delegate right at the end. Would it be wrong to make my `NSView` subclass conform to `CALayerDelegate` and implement `displayLayer`? Or is it about the same as implementing `[NSView updateLayer]`? – aleclarson Jan 16 '20 at 07:40
  • It seems that if I override `[NSView makeBackingLayer]`, I'm required to use `[CALayerDelegate displayLayer:]`. Can you confirm this? (Related answer: https://stackoverflow.com/a/53288473/2228559) – aleclarson Jan 16 '20 at 08:53
  • @aleclarson Sorry, meant to say CALayerDelegate, there is no call on CALayer. makeBackingLayer is for changing the backing CALayer class used by the NSView and yes you're on your own for managing it via the delegate callbacks. The call should generally be avoided unless you really require a different subclass. – Lucas Derraugh Jan 16 '20 at 18:09
  • Alright thanks! Any idea what disadvantages there are to returning `[CALayer layer]` from `makeBackingLayer` instead of using the default `_NSViewBackingLayer` class? – aleclarson Jan 16 '20 at 18:37
  • @aleclarson I've never really dove into the differences between the 2. I image they are rather minimal. – Lucas Derraugh Jan 16 '20 at 19:30
  • @aleclarson Don't want to be that guy, but do you think this is an acceptable answer? – Lucas Derraugh Jan 17 '20 at 16:29
1

Here are my own findings.

If you override -[NSView makeBackingLayer], you must use -[CALayerDelegate displayLayer:] instead of -[NSView updateLayer].


CALayer vs. NSViewBackingLayer

If you don't override makeBackingLayer and you set wantsLayer to YES, the default layer class is called _NSViewBackingLayer.

It behaves differently than CALayer in the following ways:

  • takes up noticeably less memory.
  • calls setNeedsDisplay:YES when its transform property is set.
  • maybe other ways too...?
aleclarson
  • 18,087
  • 14
  • 64
  • 91