问题描述
我正在尝试通过NSViewController
中的暗/亮模式切换来更改图像的颜色.我正在使用以下代码来更改图像的颜色:
I'm trying to change the colour of an image with the switching of dark/light mode in an NSViewController
.I'm using this code for changing the colour of the image:
- (NSImage *)image:(NSImage *)image withColour:(NSColor *)colour
{
NSImage *img = image.copy;
[img lockFocus];
[colour set];
NSRect imageRect = NSMakeRect(0, 0, img.size.width, img.size.height);
NSRectFillUsingOperation(imageRect, NSCompositingOperationSourceAtop);
[img unlockFocus];
return img;
}
我尝试从viewWillLayout
self.help1Image.image = [self image:self.help1Image.image withColour:[NSColor systemRedColor]];
但是似乎系统颜色总是返回相同的RGB值.
but it seems the system color always returns the same RGB values.
我也尝试过监听通知AppleInterfaceThemeChangedNotification
,但是即使在这里,似乎RGB值也保持不变.
I've also tried listening for the notification AppleInterfaceThemeChangedNotification
but even in here it seems the RGB values stay the same 1.000000 0.231373 0.188235
.
[[NSDistributedNotificationCenter defaultCenter] addObserverForName:@"AppleInterfaceThemeChangedNotification"
object:nil
queue:nil
usingBlock:^(NSNotification * _Nonnull note) {
NSLog(@"AppleInterfaceThemeChangedNotification");
self.help1Image.image = [self image:self.help1Image.image withColour:[NSColor systemRedColor]];
NSColorSpace *colorSpace = [NSColorSpace sRGBColorSpace];
NSColor *testColor = [[NSColor systemBlueColor] colorUsingColorSpace:colorSpace];
CGFloat red = [testColor redComponent];
CGFloat green = [testColor greenComponent];
CGFloat blue = [testColor blueComponent];
NSLog(@"%f %f %f", red, green, blue);
}];
我在NSButtonCell
子眼镜架中可以正常工作,并且可以覆盖layout
,但是不能在NSViewController
I have the working fine in an NSButtonCell
sublass and overriding layout
but can't get it working in an NSViewController
推荐答案
首先,查看文档部分使用特定方法更新自定义视图" 此处.它说:
First, check the documentation section "Update Custom Views Using Specific Methods" here. It says:
但是,该表中没有列出NSViewController
方法.
However, there are no NSViewController
methods listed in that table.
由于视图的外观可以独立于当前或系统"外观,因此对视图控制器中的外观变化做出反应的最佳方法是对视图的effectiveAppearance
属性进行KVO或在[NSView viewDidChangeEffectiveAppearance]
中执行操作
Since the view's appearance can be independent of the current or "system" appearance, the best way to react to appearance changes in your view controller is to either KVO the view's effectiveAppearance
property, or to do something in [NSView viewDidChangeEffectiveAppearance]
.
- (void)viewDidLoad
{
[self addObserver:self forKeyPath:@"view.effectiveAppearance" options:0 context:nil];
}
// ...
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
if ([keyPath isEqualToString:@"view.effectiveAppearance"])
{
// ...
NSAppearance
具有currentAppearance
属性,该属性与系统外观无关,并且由Cocoa按照上面列出的方法进行更新.在其他任何地方,您都需要检查自己是否正确.惯用的方法还是通过视图的effectiveAppearance
:
NSAppearance
has a currentAppearance
property which is independent of the system appearance, and updated by Cocoa in the methods listed above. Everywhere else, you will need to check that is correct yourself. The idiomatic way is, again, via the view's effectiveAppearance
:
[NSAppearance setCurrentAppearance:someView.effectiveAppearance];
因此,在您的情况下,以下内容对我来说很有效:
So, in your case, the following works well for me:
- (void)viewDidLoad
{
[super viewDidLoad];
[self addObserver:self forKeyPath:@"view.effectiveAppearance" options:0 context:nil];
}
-(void)viewDidLayout
{
self.help1Image.image = [self image:self.help1Image.image withColour:[NSColor systemRedColor]];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"view.effectiveAppearance"])
{
[NSAppearance setCurrentAppearance:self.view.effectiveAppearance];
self.help1Image.image = [self image:self.help1Image.image withColour:[NSColor systemRedColor]];
}
}
这篇关于NSColor系统切换暗/亮模式时颜色不改变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!