As of 2018, what is the correct way to create a custom control with AppKit/Cocoa?
The traditional technique has been to subclass NSControl
and/or NSCell
for the type of custom control you're implementing. (Such as an NSButton
that does custom drawing.)
However, in WWDC 2014-204 Apple stated that NSCell
is on its way to "Formal Deprecation". In WWDC 2012-217, Apple suggests subclassing NSView
and taking advantage of layer-backing and layer properties to draw a simple button.
If you subclass NSView
to create a custom control (such as a "better button") then you lose a lot of functionality that NSControl
offers, such as pre-wired action
and target
properties, mouse-tracking, keyboard activation and probably a bunch of other things I'm not even aware of.
If you subclass NSControl
, or even NSButton
, what is the correct way to take over all of the drawing? Apple's Programming Guide has not been updated regarding this. In particular, can an NSButton
subclass just override all the draw...
methods from itself and NSCell
and then just do what it wants to do in updateLayer
? Is there any guarantee that the existing NSButton/NSButtonCell
drawing code won't still do any drawing?
What if you wanted to build a button with a custom background but still uses a string-based title
or attributedTitle
? NSButton
offers this but how does the title
drawing interact with updateLayer
?
My use-case is to create a custom button that offer more visual states and more visual designs than a traditional NSButton
. Using a layer-backed NSView
and updateLayer
makes implementing all of the different states a breeze, but I'd prefer to subclass NSControl
or even NSButton
so that I also retain all of the functionality that those classes already offer.
Edit 1: Changed wording based on comments below to more accurately reflect the current deprecation state of NSCell.