设置自定义 NSView 的 backgroundColor
Setting backgroundColor of custom NSView
osx使用故事板绘制到 NSView 的过程是怎样的?我在 NSViewController 中添加了一个 NSView。然后,我添加了一些约束和一个出口。
接下来,我添加了一些代码来更改颜色:
导入 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 上进行过复杂的绘图,但我完全被困在这里。
有人看到我做错了什么吗?
这个效果好多了:
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
NSColor.blueColor().setFill()
NSRectFill(dirtyRect);
}
正确的做法是
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.
}
}}
edit/update:
另一种选择是设计您自己的彩色视图:
import Cocoa
@IBDesignable class ColoredView: NSView {
@IBInspectable var backgroundColor: NSColor = .clear
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
backgroundColor.set()
dirtyRect.fill()
}
}
然后你只需要添加一个自定义视图 NSView
并在检查器中设置自定义 class:
原答案
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
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
}
}
}
@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,尽管没有记录!
在支持 暗模式 的 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
None 的解决方案是使用 Cocoa 框架的纯粹力量。
正确的解决方案是使用 NSBox
而不是 NSView
。一直支持fillColor
、borderColor
等
- 将
titlePosition
设置为None
- 将
boxType
设置为Custom
- 将
borderType
设置为None
- 从资产目录中设置您想要的
fillColor
(深色模式很重要)
- 将
borderWidth
和borderRadius
设置为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
}
}
调色:
只需一行代码就足以改变任何NSView
对象的背景:
myView.setValue(NSColor.blue, forKey: "backgroundColor")
除此之外,您还可以在具有 keyPath backgroundColor
的 Color
类型的界面设计器中添加用户定义的属性。
osx使用故事板绘制到 NSView 的过程是怎样的?我在 NSViewController 中添加了一个 NSView。然后,我添加了一些约束和一个出口。
接下来,我添加了一些代码来更改颜色: 导入 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 上进行过复杂的绘图,但我完全被困在这里。 有人看到我做错了什么吗?
这个效果好多了:
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
NSColor.blueColor().setFill()
NSRectFill(dirtyRect);
}
正确的做法是
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.
}
}}
edit/update:
另一种选择是设计您自己的彩色视图:
import Cocoa
@IBDesignable class ColoredView: NSView {
@IBInspectable var backgroundColor: NSColor = .clear
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
backgroundColor.set()
dirtyRect.fill()
}
}
然后你只需要添加一个自定义视图 NSView
并在检查器中设置自定义 class:
原答案
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
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
}
}
}
@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,尽管没有记录!
在支持 暗模式 的 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
None 的解决方案是使用 Cocoa 框架的纯粹力量。
正确的解决方案是使用 NSBox
而不是 NSView
。一直支持fillColor
、borderColor
等
- 将
titlePosition
设置为None
- 将
boxType
设置为Custom
- 将
borderType
设置为None
- 从资产目录中设置您想要的
fillColor
(深色模式很重要) - 将
borderWidth
和borderRadius
设置为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
}
}
调色:
只需一行代码就足以改变任何NSView
对象的背景:
myView.setValue(NSColor.blue, forKey: "backgroundColor")
除此之外,您还可以在具有 keyPath backgroundColor
的 Color
类型的界面设计器中添加用户定义的属性。