I used to develop for iOS and I do not understand why I can't easily change background color of NSView
s inside my main view.
Let's say I have a view controller with a main view in it. In this view I've added 3 custom views, I've set their constraints to fit the main view.
I've created 3 outlets to my view controller:
@IBOutlet weak var topView: NSView!
@IBOutlet weak var leftView: NSView!
@IBOutlet weak var rightView: NSView!
After that, I'm trying to set the background of these views and can't do this. I don't see any color changes when I run the app.
Here is the code I've added to show colors for my custom views:
override func viewDidLoad() {
super.viewDidLoad()
self.view.wantsLayer = true
self.topView.layer?.backgroundColor = NSColor.blue.cgColor
self.rightView.layer?.backgroundColor = NSColor.green.cgColor
self.leftView.layer?.backgroundColor = NSColor.yellow.cgColor
}
And it shows nothing (no background color on my views):
I can't understand why this code doesn't work. Why it is so hard to set the color of an NSView
(while it is so easy in iOS development)? I'm using Xcode 8 and writing code using Swift 3.
You should set wantsLayer
to true
for your subviews, not for your superview.
self.topView.wantsLayer = true
self.rightView.wantsLayer = true
self.leftView.wantsLayer = true
The layer approach is convenient, but it will create a terrible issue unless you have a very dark background again a bright text color (or vice versa... I don't remember which is which any more.) for an NSTextField label. Unlike Cocoa Touch, which lets you change the background color of a UIView object, unfortunately, you have to subclass NSView in Cocoa for certainty like the following.
import Cocoa
class RedView: NSView {
override func draw(_ rect: NSRect) {
super.draw(rect)
let color = NSColor.red
color.set()
NSRectFill(rect)
}
}
Then set the class name according to whatever you call your subclass (RedView here) under the identity inspector of the interface builder. If you want to change the background color programatically, wire up the view object. Then do something like the following.
import Cocoa
class MyView: NSView {
// MARK: - Variables
var backgroundColor = NSColor()
// MARK: - Draw
override func draw(_ rect:NSRect) {
super.draw(rect)
backgroundColor.set()
NSRectFill(rect)
}
// MARK: - Method
func changeBackgroundColor(color: NSColor) {
backgroundColor = color
setNeedsDisplay(self.bounds)
}
}
You can then call changeBackgroundColor from the view controller like...
@IBOutlet weak var myView: MyView!
myView.changeBackgroundColor(color: NSColor.green)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With