Apple has "soft-deprecated" NSCell on macOS. I'm trying to reduce the use of it in my custom NSControl subclasses and, instead, use CALayers to handle my drawing. To do this, I make my NSButton subclass layer-backed:
self.wantsLayer = YES;
And then I attempt to handle my drawing using the "updateLayer" path instead of "drawRect":
- (BOOL) wantsUpdateLayer {
return YES;
}
- (void) updateLayer {
// Change layer background/border colors if pressed, disabled, etc.
// Change text color of a CATextLayer sublayer for button's title.
}
If I use -updateLayer
, the NSCell still receives drawing commands and draws its title, resulting in a "blurry" title string in my control because the string is being drawn twice—once in my textLayer and once by the Cell.
If, however, I do the exact same work as above in -drawRect:
instead of -updateLayer
, then the cell does NOT do any drawing (because I don't call down into it with [self.cell drawInteriorWithFrame:ControlView:]
)
I cannot, for the life of me, figure out what's firing the cell drawing when the associated controlView (my button subclass) has opted into -updateLayer
instead of -drawRect:
.
I have looked at all the methods on NSControl.h and NSView.h. I've overridden all of the -updateCell
and associated methods. None of those are the culprit. I cannot simply set self.cell=nil
because NSControl still relies on NSCell for event handling, etc.
Can someone tell me how to stop NSCell from drawing when its associated controlView is using -updateLayer
instead of -drawRect:
?
In -[NSButtonCell layoutLayerWithFrame:inView:]
, the cell adds a NSTextField
to draw the title. Override titleRectForBounds:
and return NSZeroRect
to remove the title.