Detecting an NSColorWell's changed selection

3.5k Views Asked by At

I have been looking at how to use an NSColorWell in my app, but there doesn't seem to be much documentation on it.

Is there any way to embed a colour picker (such as the NSColorWell/NSColorPanel) directly into my view? When clicking the well, it always presents a new colour picking window. Can this not be embedded somehow?

I have a custom NSButton class to which I am passing the colour from my NSColorWell. To do this, I am having to make the user pick a colour, then click a button to send this colour to my custom class. Is there a way of simply detecting when a new colour is selected directly from the color picker?

3

There are 3 best solutions below

1
On BEST ANSWER

For problem 1, no, that's the system behaviour for an NSColorWell. Don't like it? make your own.

Problem 2 has two possible solutions.

Method 1: Connect the action from the color well to your object in IB and read the color of the color well via an outlet from your class. Any color change in the well will send a message to the selector of your choice.

Method 2: Add an object of your own as an observer to the color property

[colorwell addObserver:self forKeyPath:@"color" options:0 context:NULL];

then implement

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

Any color change will trigger that method.

Be sure to detach from the color well in dealloc or another breakdown method:

[colorwell removeObserver:self forKeyPath:@"color"]

There's a way to do it with bindings as well, but these two are fine.

0
On

For swift 2 I use this code:

@IBOutlet weak var colorSelector: NSColorWell!

    override func viewDidAppear() {
        super.viewDidAppear()

        self.colorSelector.addObserver(self, forKeyPath: "color", options: .New, context: nil)

    }

    override func viewDidDisappear(){
        super.viewDidDisappear()

        self.colorSelector.removeObserver(self, forKeyPath:"color")
    }

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        print("keyPath=>\(keyPath)")

        if (keyPath! == "color") {
            print("object=>\(self.colorSelector.color)")
        } 
    }
0
On

For the color panel problem, I was also looking for such a thing. The closes I could find was this one on CocoaControls. Unfortunately, this only works on 10.7+ (as it uses NSPopover) and it looks like it uses a private API.