Часть решения может включать пользовательские (круглые, зеленые) кнопки.Чтобы создать кнопку с красным фоном (как предупреждение от критических действий), я разделил NSButton на подклассы:
class ColorButton: NSButton
и метод рисования (...).
Это дало мне контроль над внешностью.Все остальное поведение унаследовано от NSButton.
Кроме того, теги @IBDesignable и @IBInspectable открыли пользовательский элемент управления в InterfaceBuilder.
Это было легко.Правильный внешний вид был нетривиальной задачей (для меня), поскольку у кнопок Какао есть некоторые тонкие поведения (например, отключенный, выделение цветом).Реагирование на параметры цвета рабочего стола (такие как режим темного цвета) также является соображением.
Вот код для моей ColorButton, который, опять же, должен был изменить цвет фона, а не форму.
@IBDesignable
class ColorButton: NSButton {
@IBInspectable var backgroundColor: NSColor = NSColor.controlBackgroundColor
{ didSet { needsDisplay = true } }
@IBInspectable var textColor: NSColor = NSColor.controlTextColor
override func draw(_ dirtyRect: NSRect)
{
// fill in background with regular or highlight color
var backgroundColor = (isHighlighted ? self.backgroundColor.highlight(withLevel: 0.75) : isEnabled ? self.backgroundColor : NSColor.gray)!
if isEnabled == false { backgroundColor = NSColor.lightGray }
let textColor = (isEnabled ? self.textColor : NSColor.disabledControlTextColor )
var rect: NSRect = NSRect(x: 7.0, y: 5.0, width: self.frame.width - 14.0, height: self.frame.height - 13.0) // self.frame// dirtyRect
var path = NSBezierPath(roundedRect: rect, xRadius: 4.0, yRadius: 4.0)
backgroundColor.setFill()
NSColor.darkGray.setStroke()
path.lineWidth = 0
path.fill()
path.stroke()
let font = NSFont(name: "Helvetica", size: (rect.height) * 0.66)
let text = title as NSString
let textFontAttributes = [convertFromNSAttributedStringKey(NSAttributedString.Key.font): font!, convertFromNSAttributedStringKey(NSAttributedString.Key.foregroundColor): textColor] as [String : Any]
let size = text.size(withAttributes: convertToOptionalNSAttributedStringKeyDictionary(textFontAttributes))
let location = NSPoint(x: ((self.frame.width - size.width) / 2.0), y: ((self.frame.height - size.height) / 2.0) - 3.0)
text.draw(at: location, withAttributes: convertToOptionalNSAttributedStringKeyDictionary(textFontAttributes))
}// draw
}
Выше был разработан в Swift 3. Добавлен инструмент миграции Swift 4:
// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromNSAttributedStringKey(_ input: NSAttributedString.Key) -> String {
return input.rawValue
}
// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToOptionalNSAttributedStringKeyDictionary(_ input: [String: Any]?) -> [NSAttributedString.Key: Any]? {
guard let input = input else { return nil }
return Dictionary(uniqueKeysWithValues: input.map { key, value in (NSAttributedString.Key(rawValue: key), value)})
}