Best way to change the background color for an NSView

Objective CMacosBackground ColorNsview

Objective C Problem Overview


I'm looking for the best way to change the backgroundColor of an NSView. I'd also like to be able to set the appropriate alpha mask for the NSView. Something like:

myView.backgroundColor = [NSColor colorWithCalibratedRed:0.227f 
                                                   green:0.251f 
                                                    blue:0.337 
                                                   alpha:0.8];

I notice that NSWindow has this method, and I'm not a big fan of the NSColorWheel, or NSImage background options, but if they are the best, willing to use.

Objective C Solutions


Solution 1 - Objective C

Yeah, your own answer was right. You could also use Cocoa methods:

- (void)drawRect:(NSRect)dirtyRect {
    // set any NSColor for filling, say white:
	[[NSColor whiteColor] setFill];
	NSRectFill(dirtyRect);
    [super drawRect:dirtyRect];
}

In Swift:

class MyView: NSView {

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
        
        // #1d161d
        NSColor(red: 0x1d/255, green: 0x16/255, blue: 0x1d/255, alpha: 1).setFill()
        dirtyRect.fill()
    }
    
}

Solution 2 - Objective C

An easy, efficient solution is to configure the view to use a Core Animation layer as its backing store. Then you can use -[CALayer setBackgroundColor:] to set the background color of the layer.

- (void)awakeFromNib {
   self.wantsLayer = YES;  // NSView will create a CALayer automatically
}

- (BOOL)wantsUpdateLayer {
   return YES;  // Tells NSView to call `updateLayer` instead of `drawRect:`
}

- (void)updateLayer {
   self.layer.backgroundColor = [NSColor colorWithCalibratedRed:0.227f 
                                                          green:0.251f 
                                                           blue:0.337 
                                                          alpha:0.8].CGColor;
}

That’s it!

Solution 3 - Objective C

If you are a storyboard lover, here is a way that you don't need any line of code.

Add NSBox as a subview to NSView and adjust NSBox's frame as the same with NSView.

In Storyboard or XIB change Title position to None, Box type to Custom, Border Type to "None", and Border color to whatever you like.

Here is a screenshot:

enter image description here

This is the result:

enter image description here

Solution 4 - Objective C

If you setWantsLayer to YES first, you can directly manipulate the layer background.

[self.view setWantsLayer:YES];
[self.view.layer setBackgroundColor:[[NSColor whiteColor] CGColor]];

Solution 5 - Objective C

Think I figured out how to do it:

- (void)drawRect:(NSRect)dirtyRect {
    // Fill in background Color
	CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
	CGContextSetRGBFillColor(context, 0.227,0.251,0.337,0.8);
	CGContextFillRect(context, NSRectToCGRect(dirtyRect));
}

Solution 6 - Objective C

I went through all of these answers and none of them worked for me unfortunately. However, I found this extremely simple way, after about an hour of searching : )

myView.layer.backgroundColor = CGColorCreateGenericRGB(0, 0, 0, 0.9);

Solution 7 - Objective C

edit/update: Xcode 8.3.1 • Swift 3.1

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
        }
    }
}

usage:

let myView = NSView(frame: NSRect(x: 0, y: 0, width: 100, height: 100))
print(myView.backgroundColor ?? "none")     //  NSView's background hasn't been set yet = nil
myView.backgroundColor = .red               // set NSView's background color to red color
print(myView.backgroundColor ?? "none")
view.addSubview(myView)

Solution 8 - Objective C

Best Solution :

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.wantsLayer = YES;
    }
    return self;
}

- (void)awakeFromNib
{
    float r = (rand() % 255) / 255.0f;
    float g = (rand() % 255) / 255.0f;
    float b = (rand() % 255) / 255.0f;
    
    if(self.layer)
    {
        CGColorRef color = CGColorCreateGenericRGB(r, g, b, 1.0f);
        self.layer.backgroundColor = color;
        CGColorRelease(color);
    }
}

Solution 9 - Objective C

In Swift:

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

Solution 10 - Objective C

Use NSBox, which is a subclass of NSView, allowing us to easily style

Swift 3

let box = NSBox()
box.boxType = .custom
box.fillColor = NSColor.red
box.cornerRadius = 5

Solution 11 - Objective C

Without doubt the easiest way, also compatible with Color Set Assets:

Swift:

view.setValue(NSColor.white, forKey: "backgroundColor")

Objective-C:

[view setValue: NSColor.whiteColor forKey: "backgroundColor"];

Interface Builder:

Add a user defined attribute backgroundColor in the interface builder, of type NSColor.

Solution 12 - Objective C

Just set backgroundColor on the layer (after making the view layer backed).

view.wantsLayer = true
view.layer?.backgroundColor = CGColor.white

Solution 13 - Objective C

I tested the following and it worked for me (in Swift):

view.wantsLayer = true
view.layer?.backgroundColor = NSColor.blackColor().colorWithAlphaComponent(0.5).CGColor

Solution 14 - Objective C

In Swift 3, you can create an extension to do it:

extension NSView {
    func setBackgroundColor(_ color: NSColor) {
        wantsLayer = true
        layer?.backgroundColor = color.cgColor
    }
}

// how to use
btn.setBackgroundColor(NSColor.gray)

Solution 15 - Objective C

In swift you can subclass NSView and do this

class MyView:NSView {
    required init?(coder: NSCoder) {
        super.init(coder: coder);
        
        self.wantsLayer = true;
        self.layer?.backgroundColor = NSColor.redColor().CGColor;
    }
}

Solution 16 - Objective C

This supports changing systemwide appearance (turning dark mode on or off) while the application is running. You can also set the background colour in Interface Builder, if you set the class of the view to BackgroundColorView first.


class BackgroundColorView: NSView {
	@IBInspectable var backgroundColor: NSColor? {
		didSet { needsDisplay = true }
	}

	override init(frame frameRect: NSRect) {
		super.init(frame: frameRect)
		wantsLayer = true
	}

	required init?(coder decoder: NSCoder) {
		super.init(coder: decoder)
		wantsLayer = true
	}

	override var wantsUpdateLayer: Bool { return true }

	override func updateLayer() {
		layer?.backgroundColor = backgroundColor?.cgColor
	}
}

Solution 17 - Objective C

Have a look at [RMSkinnedView][1]. You can set the NSView's background color from within Interface Builder.

[1]: https://github.com/raffael/RMSkinnedView "RMSkinnedView"

Solution 18 - Objective C

Just small reusable class (Swift 4.1)

class View: NSView {

   var backgroundColor: NSColor?

   convenience init() {
      self.init(frame: NSRect())
   }

   override func draw(_ dirtyRect: NSRect) {
      if let backgroundColor = backgroundColor {
         backgroundColor.setFill()
         dirtyRect.fill()
      } else {
         super.draw(dirtyRect)
      }
   }
}

// Usage
let view = View()
view.backgroundColor = .white

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBadPirateView Question on Stackoverflow
Solution 1 - Objective CmohsenrView Answer on Stackoverflow
Solution 2 - Objective CloretoparisiView Answer on Stackoverflow
Solution 3 - Objective CJZAUView Answer on Stackoverflow
Solution 4 - Objective CGabrielView Answer on Stackoverflow
Solution 5 - Objective CBadPirateView Answer on Stackoverflow
Solution 6 - Objective CgreenhouseView Answer on Stackoverflow
Solution 7 - Objective CLeo DabusView Answer on Stackoverflow
Solution 8 - Objective CNagarajView Answer on Stackoverflow
Solution 9 - Objective CUserView Answer on Stackoverflow
Solution 10 - Objective Conmyway133View Answer on Stackoverflow
Solution 11 - Objective CElyView Answer on Stackoverflow
Solution 12 - Objective CGeri BorbásView Answer on Stackoverflow
Solution 13 - Objective CTyler LiuView Answer on Stackoverflow
Solution 14 - Objective CKaiyuan XuView Answer on Stackoverflow
Solution 15 - Objective CChad SciraView Answer on Stackoverflow
Solution 16 - Objective CkaremanView Answer on Stackoverflow
Solution 17 - Objective CRaffaelView Answer on Stackoverflow
Solution 18 - Objective CVladView Answer on Stackoverflow