设置自定义NSView的backgroundColor

时间:2015-01-11 17:46:11

标签: swift nsview xcode-storyboard

使用osx的故事板绘制到NSView的过程是什么?我已经在NSViewController中添加了一个NSView。然后,我添加了一些约束和插座。 enter image description here

接下来,我添加了一些代码来改变颜色: 导入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上进行过复杂的绘图,但我完全陷入困境。 有谁看到我做错了什么?

9 个答案:

答案 0 :(得分:33)

正确的方法是

class ViewController: NSViewController {

@IBOutlet var box: NSView!

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

}

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

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

答案 1 :(得分:30)

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

yourView NSView 或其任何子类

更新了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
        }
    }
}

答案 2 :(得分:10)

编辑/更新:

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

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

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

Custom View

ColoredView

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

答案 3 :(得分:4)

这样做效果更好:

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

答案 4 :(得分:1)

只需一行代码即可更改任何NSView对象的背景:

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

相反,您还可以在类型为Color的接口设计器中使用keyPath backgroundColor添加用户定义的属性。

答案 5 :(得分:0)

@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

            }

        }
    }
}

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

1 / 在Assets.xcassets中创建颜色 enter image description here

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

答案 8 :(得分:0)

所有解决方案均未使用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 +系统颜色将完全应用着色。如果您不想着色,请使用目录颜色。

enter image description here

替代方法是提供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
    }
}

着色: enter image description here