问题描述
您可以看到 Apple 为单选按钮着色。我也想这样做。我似乎无法在情节提要的 Interface Builder 中找到更改颜色的选项。
至于这样做,以编程方式,我尝试启用图层 .wantsLayer = true
,然后尝试通过 .layer?.borderColour = NSColor.systemBlue.cgColor
设置颜色并尝试使用 .layer?.backgroundColor = NSColor.systemRed.cgColor
和其他类似属性但无济于事。
同样,如何在 NSMenuItem
上的 NSPopUpButton
上添加颜色矩形?
解决方法
以下代码演示了一组通过子类化 NSButton 为 MacOS 制作的自定义单选按钮。它可以通过复制/粘贴到新添加的名为“main.swift”的文件并删除原始 AppDelegate 来在 Xcode swift 项目中运行。
import Cocoa
class CustomButton: NSButton {
var circleColor: NSColor!
override func draw(_ rect: NSRect) {
let circle = NSBezierPath(ovalIn: bounds)
switch(self.tag) {
case 0:
circleColor = NSColor.red
case 1:
circleColor = NSColor.green
case 2:
circleColor = NSColor.yellow
case 3:
circleColor = NSColor.orange
default:
break
}
circleColor.set()
circle.fill()
if(self.state) == .on {
let dotRect = NSInsetRect(bounds,18.0,18.0);
let dot = NSBezierPath (ovalIn:dotRect)
let dotColor = NSColor.black
dotColor.set()
dot.fill()
}
}
}
class AppDelegate: NSObject,NSApplicationDelegate {
var window: NSWindow!
@objc func radioGrpAction(_ sender:NSButton) {
print("You selected: id = \(sender.tag)")
}
func buildMenu() {
let mainMenu = NSMenu()
NSApp.mainMenu = mainMenu
// **** App menu **** //
let appMenuItem = NSMenuItem()
mainMenu.addItem(appMenuItem)
let appMenu = NSMenu()
appMenuItem.submenu = appMenu
appMenu.addItem(withTitle: "Quit",action:#selector(NSApplication.terminate),keyEquivalent: "q")
}
func buildWnd() {
let _wndW : CGFloat = 300
let _wndH : CGFloat = 200
window = NSWindow(contentRect:NSMakeRect(0,_wndW,_wndH),styleMask:[.titled,.closable,.miniaturizable],backing:.buffered,defer:false)
window.center()
window.title = "Radio Button Group"
window.makeKeyAndOrderFront(window)
// === Radio Grp Box === //
let grpBox = NSBox(frame: NSMakeRect( 50,_wndH - 100,150,60))
grpBox.title = "Radio Group"
window.contentView!.addSubview (grpBox)
// === Radio Horizontal Grid === //
let _btnW : CGFloat = 24
let _btnH : CGFloat = 24
let _left : CGFloat = 10 // left margin first button
let _YOffset : CGFloat = 5 // 0,0 at left,bottom of group box
let _spacing : CGFloat = 5 // spacing between buttons
for x in stride(from:0,through:3,by:1) {
let _XOffset = _left + CGFloat(x)*(_btnW + _spacing)
let btn = CustomButton(frame:NSMakeRect(_XOffset,_YOffset,_btnW,_btnH))
btn.setButtonType(.radio)
btn.tag = x
if(x == 0){btn.state = .on}
btn.action = #selector(self.radioGrpAction(_:))
grpBox.contentView!.addSubview(btn)
}
// === Quit btn === //
let quitBtn = NSButton (frame:NSMakeRect( _wndW - 50,10,40,40 ))
quitBtn.bezelStyle = .circular
quitBtn.title = "Q"
quitBtn.action = #selector(NSApplication.terminate)
window.contentView!.addSubview(quitBtn)
}
func applicationDidFinishLaunching(_ notification: Notification) {
buildMenu()
buildWnd()
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}
let appDelegate = AppDelegate()
// ***** main.swift ***** //
let app = NSApplication.shared
app.setActivationPolicy(.regular)
app.delegate = appDelegate
app.activate(ignoringOtherApps:true)
app.run()
,
好的,但对于 AppKit:
import Cocoa
import AppKit
extension NSView {
func centerX(inView view: NSView,constant: CGFloat = 0) {
translatesAutoresizingMaskIntoConstraints = false
centerXAnchor.constraint(equalTo: view.centerXAnchor,constant: constant).isActive = true
}
func centerY(inView view: NSView,constant: CGFloat = 0) {
translatesAutoresizingMaskIntoConstraints = false
centerYAnchor.constraint(equalTo: view.centerYAnchor,constant: constant).isActive = true
}
func setDimensions(height: CGFloat,width: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
heightAnchor.constraint(equalToConstant: height).isActive = true
widthAnchor.constraint(equalToConstant: width).isActive = true
}
}
class CustomRadioButton: NSView {
private let containerSize: CGFloat = 60.0
private let selectorSize: CGFloat = 20.0
var containerColor: NSColor = .blue
var selectorColor: NSColor = .red
var selected: Bool = true {
didSet {
selectorView.isHidden = !selected
}
}
private lazy var containerView: NSView = {
let view = NSView()
view.wantsLayer = true
view.layer?.backgroundColor = containerColor.cgColor
return view
}()
private lazy var selectorView: NSView = {
let view = NSView()
view.wantsLayer = true
view.layer?.backgroundColor = selectorColor.cgColor
return view
}()
override init(frame: CGRect) {
super.init(frame: CGRect(x: 0,y: 0,width: containerSize,height: containerSize))
configureUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configureUI() {
addSubview(containerView)
containerView.setDimensions(height: containerSize,width: containerSize)
containerView.layer?.cornerRadius = containerSize / 2
containerView.centerX(inView: self)
containerView.centerY(inView: self)
addSubview(selectorView)
selectorView.setDimensions(height: selectorSize,width: selectorSize)
selectorView.layer?.cornerRadius = selectorSize / 2
selectorView.centerY(inView: containerView)
selectorView.centerX(inView: containerView)
}
}
let selector = CustomRadioButton()
selector.selected = false