I am currently working on a custom themed NSButton
. Every tutorial, or guide I have found requires to subclass NSButtonCell
, even the guide from Apple.
All of those seem to be outdated, because all cell methods in NSControl
are deprecated in Yosemite. I have not found any recommendations or guides what to use as a substitute.
This is the only statement, I could find:
Gradual deprecation of NSCell
Mac OS X 10.10 takes another step towards the eventual deprecation of cells. Direct access to the cell of a control is discouraged, and methods which allow it will be formally deprecated in a subsequent release. A variety of cell-level APIs have been promoted to various Control subclasses in order to provide cell-free access to important functionality. NSLevelIndicator, NSTextField, NSSearchField, NSSlider, and NSPathControl all have new properties for this purpose. Cell-based NSTableViews are now deprecated, and view-based NSTableViews should be used instead. Matrix-based NSBrowsers are also deprecated in favor of the item-based interface.
Excerpt from: AppKit Release Notes for OS X v10.10
No words on NSButton
though.
NSTextField
supports layer backed views; because of that, I tried the same approach on my NSButton
, but that has no effect.
var btn = NSButton(NSMakeRect(0, 0, 50, 20))
btn.wantsLayer = true
btn.bordered = false
btn.layer?.backgroundColor = NSColor(calibratedWhite: 0.99, alpha: 1).CGColor
btn.layer?.borderWidth = 1
btn.layer?.borderColor = NSColor(calibratedWhite: 0.81, alpha: 1).CGColor
I would definitely spend more time looking into the layer-backed view
approach. I'm not sure why it didn't work for you because there's no reason for layers not to work on an NSButton
(effectively an NSView
derivative).
Also weighing on looking more into layers is your mentioning of animation.
Some code extracted from a project I am working on (custom NSButton
):
From init()...
self.wantsLayer = true
self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawPolicy.OnSetNeedsDisplay
self.layer?.borderColor = NSColor.gridColor().CGColor
self.layer?.borderWidth = 0.5
self.layer?.backgroundColor = NSColor.whiteColor().CGColor
You can then get fine-grained control in the display cycle specific to layers with:
override var wantsUpdateLayer:Bool{
return true
}
override func updateLayer() {
// your code here
super.updateLayer()
}
If your custom button needs a shape then you can even use a CAShapeLayer below to make your backing layer a special shape...more detail to be looked into.
override func makeBackingLayer() -> CALayer {
return CAShapeLayer()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With