如何在不创建NSButtonCell子类的情况下创建自定义主题NSButton?

Aft*_*ame 21 macos cocoa swift

我目前正致力于定制主题NSButton.我发现的每个教程或指南都需要子类化NSButtonCell,甚至是Apple的指南.

所有这些似乎都已过时,因为所有的单元格方法NSControl在Yosemite中被弃用.我没有找到任何建议或指导用作替代品.

这是唯一的陈述,我能找到:

逐步弃用NSCell

Mac OS X 10.10向最终弃用单元格迈出了一步.不鼓励直接访问控件的单元格,允许它的方法将在后续版本中正式弃用.各种单元级API已被提升为各种Control子类,以便提供对无重要功能的无单元访问.NSLevelIndicator,NSTextField,NSSearchField,NSSlider和NSPathControl都具有用于此目的的新属性.现在不推荐使用基于单元格的NSTableViews,而应使用基于视图的NSTableViews.基于矩阵的NSBrowser也不推荐使用基于项目的界面.

摘录自:适用于OS X v10.10的AppKit发行说明

NSButton虽然没有言论.

NSTextField支持图层支持的视图; 因此,我尝试了同样的方法NSButton,但这没有效果.

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
Run Code Online (Sandbox Code Playgroud)

Sam*_*Sam 4

我肯定会花更多时间研究该layer-backed view方法。我不确定为什么它对你不起作用,因为没有理由层不能在NSButton(实际上是NSView衍生品)上工作。

您提到的动画也值得更多地研究图层。

从我正在处理的项目中提取的一些代码(自定义NSButton):

从 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
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过以下方式在特定于图层的显示周期中获得细粒度的控制:

override var wantsUpdateLayer:Bool{
    return true
}

override func updateLayer() {
    // your code here
    super.updateLayer()
}
Run Code Online (Sandbox Code Playgroud)

如果您的自定义按钮需要形状,那么您甚至可以使用下面的 CAShapeLayer 使您的背衬层成为特殊形状......更多细节需要研究。

override func makeBackingLayer() -> CALayer {
    return CAShapeLayer()
}
Run Code Online (Sandbox Code Playgroud)