如何手动创建动态 (dark/light) NSImage 实例?
How to manually create dynamic (dark/light) NSImage instances?
在 macOS 10.14 Mojave 中,创建自动绘制明暗版本的 NSImage
实例的唯一方法是通过资产目录和 +[NSImage imageNamed:]
。但是,我需要在运行时创建动态图像,而且似乎没有办法不使用 private API.
在幕后,似乎已将私有 属性 _appearanceName
引入 NSImageRep
,以某种方式用于 select 正确的表示。使用具有相应 _appearanceName
集的图像表示创建 NSImage
应该是直截了当的,但我想避免这种情况。
我找到了一个简单的解决方法(在下面发布)但是当系统外观发生变化时(即用户从浅色切换到深色或反之亦然)或者在具有appearance
属性 设置为不同的外观(例如,一个视图硬编码为暗模式,另一个视图硬编码为亮模式)。
那么,我怎样才能手动创建动态 NSImage
来正确显示浅色或深色版本,就像资产目录图像那样?
@implementation NSImage (CustomDynamic)
+ (NSImage *)imageWithLight:(NSImage *)light dark:(NSImage *)dark
{
if (@available(macOS 10.14, *)) {
return [NSImage
imageWithSize:light.size
flipped:NO
drawingHandler:^(NSRect dstRect) {
if ([NSImage appearanceIsDarkMode:NSAppearance.currentAppearance]) {
[dark drawInRect:dstRect];
} else {
[light drawInRect:dstRect];
}
return YES;
}
];
} else {
return light;
}
}
+ (BOOL)appearanceIsDarkMode:(NSAppearance *)appearance
{
if (@available(macOS 10.14, *)) {
NSAppearanceName basicAppearance = [appearance bestMatchFromAppearancesWithNames:@[
NSAppearanceNameAqua,
NSAppearanceNameDarkAqua
]];
return [basicAppearance isEqualToString:NSAppearanceNameDarkAqua];
} else {
return NO;
}
}
@end
呃,原来问题中发布的代码工作得很好!绘图处理程序 是 实际上会在适当的时候调用并且 确实 处理所有外观情况。
但是,我有缩放和缓存这些图像的代码,它仍在使用古老的 [image lockFocus]; … [image unlockFocus];
绘制图像的方式,而不是使用 +[NSImage imageWithSize:flipped:drawingHandler:]
。
在 macOS 10.14 Mojave 中,创建自动绘制明暗版本的 NSImage
实例的唯一方法是通过资产目录和 +[NSImage imageNamed:]
。但是,我需要在运行时创建动态图像,而且似乎没有办法不使用 private API.
在幕后,似乎已将私有 属性 _appearanceName
引入 NSImageRep
,以某种方式用于 select 正确的表示。使用具有相应 _appearanceName
集的图像表示创建 NSImage
应该是直截了当的,但我想避免这种情况。
我找到了一个简单的解决方法(在下面发布)但是当系统外观发生变化时(即用户从浅色切换到深色或反之亦然)或者在具有appearance
属性 设置为不同的外观(例如,一个视图硬编码为暗模式,另一个视图硬编码为亮模式)。
那么,我怎样才能手动创建动态 NSImage
来正确显示浅色或深色版本,就像资产目录图像那样?
@implementation NSImage (CustomDynamic)
+ (NSImage *)imageWithLight:(NSImage *)light dark:(NSImage *)dark
{
if (@available(macOS 10.14, *)) {
return [NSImage
imageWithSize:light.size
flipped:NO
drawingHandler:^(NSRect dstRect) {
if ([NSImage appearanceIsDarkMode:NSAppearance.currentAppearance]) {
[dark drawInRect:dstRect];
} else {
[light drawInRect:dstRect];
}
return YES;
}
];
} else {
return light;
}
}
+ (BOOL)appearanceIsDarkMode:(NSAppearance *)appearance
{
if (@available(macOS 10.14, *)) {
NSAppearanceName basicAppearance = [appearance bestMatchFromAppearancesWithNames:@[
NSAppearanceNameAqua,
NSAppearanceNameDarkAqua
]];
return [basicAppearance isEqualToString:NSAppearanceNameDarkAqua];
} else {
return NO;
}
}
@end
呃,原来问题中发布的代码工作得很好!绘图处理程序 是 实际上会在适当的时候调用并且 确实 处理所有外观情况。
但是,我有缩放和缓存这些图像的代码,它仍在使用古老的 [image lockFocus]; … [image unlockFocus];
绘制图像的方式,而不是使用 +[NSImage imageWithSize:flipped:drawingHandler:]
。