I am looking into theming my app by setting window.appearance
.
In my app, I draw some stuff inside layers. I also use Core Plot, which renders its charts in layers.
For the default aqua appearance, I just use the system colors (such as NSColor.textColor
and NSColor.gridColor
) and they are drawn in the correct color in CALayer
. But changing the window's appearance to vibrant dark causes colors to be drawn incorrectly.
Is there any way to obtain the correct color for a given
NSAppearance? Private API is acceptable too.
If the question is not clear, here is a very simple example to show the problem.
I set up a CATextLayer
that is added as a sublayer of the main view's sublayers and an NSTextFied
that is added as a subview:
CATextLayer* textLayer = [CATextLayer new];
textLayer.string = @"Is this colored correctly? (Layer)";
textLayer.foregroundColor = NSColor.textColor.CGColor;
textLayer.contentsScale = 2.0;
textLayer.frame = (CGRect){0,0, [textLayer preferredFrameSize]};
NSTextField* textField = [NSTextField new];
textField.stringValue = @"Is this colored correctly? (View)";
textField.textColor = NSColor.textColor;
textField.font = (__bridge id)textLayer.font;
textField.editable = NO;
textField.selectable = NO;
textField.bezeled = NO;
textField.backgroundColor = nil;
[textField sizeToFit];
textField.frame = (CGRect){0, 60, textField.bounds.size};
[self.view.layer addSublayer:textLayer];
[self.view addSubview:textField];
On an Aqua window, both appear correctly:
However, on a dark vibrant window, the layer does not, while the text field does:
I'd like to know how to get the correct color for a given NSAppearance
.
So I had an incorrect approach.
The right way to do it, is to implement -updateLayer
in the view and take the colors' CGColor
snapshot there. -updateLayer
is called when the appearance changes, so the view can update it with the correct color values.