繁体   English   中英

设置自定义 NSView 的 backgroundColor

[英]Setting backgroundColor of custom NSView

使用 osx 的故事板绘制到 NSView 的过程是什么? 我在 NSViewController 中添加了一个 NSView。 然后,我添加了一些约束和一个出口。在此处输入图片说明

接下来,我添加了一些代码来更改颜色:import Cocoa

class ViewController: NSViewController {

    @IBOutlet var box: NSView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear() {
        box.layer?.backgroundColor = NSColor.blueColor().CGColor
        //box.layer?.setNeedsDisplay()
    }

    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    } 
}

我想做 NSView 的自定义绘图和更改颜色。 我过去曾在 iOS 上进行过复杂的绘图,但完全被困在这里。 有没有人看到我做错了什么?

正确的方法是

class ViewController: NSViewController {

@IBOutlet var box: NSView!

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.wantsLayer = true

}

override func viewWillAppear() {
    box.layer?.backgroundColor = NSColor.blue.cgColor
    //box.layer?.setNeedsDisplay()
}

override var representedObject: AnyObject? {
    didSet {
    // Update the view, if already loaded.
    }
}}

Swift通过属性

extension NSView {

    var backgroundColor: NSColor? {
        get {
            if let colorRef = self.layer?.backgroundColor {
                return NSColor(CGColor: colorRef)
            } else {
                return nil
            }
        }
        set {
            self.wantsLayer = true
            self.layer?.backgroundColor = newValue?.CGColor
        }
    }   
}

用法:

    yourView.backgroundColor = NSColor.greenColor()

其中yourViewNSView或其任何子类

为 Swift 3 更新

extension NSView {

    var backgroundColor: NSColor? {

        get {
            if let colorRef = self.layer?.backgroundColor {
                return NSColor(cgColor: colorRef)
            } else {
                return nil
            }
        }

        set {
            self.wantsLayer = true
            self.layer?.backgroundColor = newValue?.cgColor
        }
    }
}

编辑/更新:

另一种选择是设计自己的彩色视图:

import Cocoa
@IBDesignable class ColoredView: NSView {
    @IBInspectable var backgroundColor: NSColor = .clear
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
        backgroundColor.set()
        dirtyRect.fill()
    }
}

然后你只需要添加一个自定义视图NSView并在检查器中设置自定义类:

自定义视图

彩色视图

IBInspectable


原答案

Swift 3.0 或更高版本

extension NSView {
    var backgroundColor: NSColor? {
        get {
            guard let color = layer?.backgroundColor else { return nil }
            return NSColor(cgColor: color)
        }
        set {
            wantsLayer = true
            layer?.backgroundColor = newValue?.cgColor
        }
    }
}

let myView = NSView(frame: NSRect(x: 0, y: 0, width: 100, height: 100))
myView.backgroundColor = .red

这效果更好:

    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)
        NSColor.blueColor().setFill()
        NSRectFill(dirtyRect);
    }

在支持暗模式的MacOS 10.14 中设置 NSView 背景颜色的最佳方法:

1/在 Assets.xcassets 中创建你的颜色在此处输入图片说明

2/子类化您的 NSView 并添加以下内容:

class myView: NSView {
    override func updateLayer() {
       self.layer?.backgroundColor = NSColor(named: "customControlColor")?.cgColor
    }
}

非常简单和暗模式支持您选择的颜色!

完整指南: https : //developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface

只需一行代码就足以改变任何NSView对象的背景:

myView.setValue(NSColor.blue, forKey: "backgroundColor")

取而代之的是,您还可以在具有 keyPath backgroundColor Color类型的界面设计器中添加用户定义的属性。

@CryingHippo 更新到 Swift 3 解决方案(在我的情况下,它不是每次运行都显示颜色)。 我添加了 DispatchQueue.main.async,现在它在应用程序的每次运行中显示颜色。

extension NSView {

    var backgroundColor: NSColor? {

        get {
            if let colorRef = self.layer?.backgroundColor {
                return NSColor(cgColor: colorRef)
            } else {
                return nil
            }
        }

        set {

            DispatchQueue.main.async { 

                self.wantsLayer = true
                self.layer?.backgroundColor = newValue?.cgColor

            }

        }
    }
}

由于 macOS 10.13 (High Sierra) NSView 响应选择器 backgroundColor 虽然它没有记录!

没有一个解决方案是使用 Cocoa 框架的纯功能。 正确的解决方案是使用NSBox而不是NSView 它一直支持fillColorborderColor等。

  1. titlePosition设置为None
  2. boxType设置为Custom
  3. borderType设置为None
  4. 从资产目录中设置所需的fillColor (对于暗模式很重要)
  5. borderWidthborderRadius设置为0

奖金:

  • 它对外观的突然变化做出动态反应(从亮到暗)
  • 它支持动画(不需要dynamic + 不需要override animation(forKey key:NSAnimatablePropertyKey) ->
  • 未来的 macOS 自动支持

警告:

  • 在暗模式下使用 NSBox + 系统颜色将正确应用着色。 如果您不想着色,请使用目录颜色。

在此处输入图片说明

另一种方法是提供 NSView 的子类并在updateLayer进行绘图更新

import Cocoa

@IBDesignable
class CustomView: NSView {

    @IBInspectable var backgroundColor : NSColor? {
        didSet { needsDisplay = true }
    }
    override var wantsUpdateLayer: Bool {
        return true
    }

    override func updateLayer() {
        guard let layer = layer else { return }
        layer.backgroundColor = backgroundColor?.cgColor
    }
}

调色: 在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM