【问题标题】:How to colour radio buttons?如何为单选按钮着色?
【发布时间】:2021-02-03 14:51:49
【问题描述】:

您可以看到 Apple 已为单选按钮着色。我也想这样做。我似乎在情节提要的 Interface Builder 中找不到更改颜色的选项。

至于这样做,以编程方式,我尝试启用层.wantsLayer = true,然后尝试通过.layer?.borderColour = NSColor.systemBlue.cgColor 设置颜色并尝试.layer?.backgroundColor = NSColor.systemRed.cgColor 和其他类似属性,但无济于事。

同样,如何在NSMenuItem 上添加颜色矩形NSPopUpButton

【问题讨论】:

    标签: swift cocoa colors appkit nsbutton


    【解决方案1】:

    以下代码演示了一组通过继承 NSButton 为 MacOS 定制的单选按钮。它可以在 Xcode swift 项目中运行,方法是复制/粘贴到新添加的名为“main.swift”的文件中并删除原始 AppDelegate。

    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,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()
    
    
    

    【讨论】:

    • 你能告诉我它应该是什么样子吗?它看起来一点也不像单选按钮。我有一个椭圆形,看起来完全不同。
    • 感谢截图!我无法让单选按钮看起来像您的屏幕截图。我创建了一个测试 Xcode 项目。在视图控制器上添加了一个单选按钮,并通过 Interface Builder 添加了子类 CustomButton,它看起来与您的屏幕截图完全不同。
    • 这是一个独立的演示;需要从 Xcode swift 项目中的“main.swift”文件运行。
    • 我让你的代码按原样工作。但我想在带有AppDelegate.swift 文件的实际应用程序中使用它。我的意思是我复制了CustomButton 并通过Interface Builder 将它作为故事板上的子类添加到单选按钮中。 CustomButton 子类应该适用于任何项目。
    • 如果您觉得它有用,请您通过检查作为答案给我信用吗?
    【解决方案2】:

    好的,但对于 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-28
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      • 2021-05-31
      • 2019-10-03
      • 2016-12-16
      • 2021-12-24
      相关资源
      最近更新 更多