Похоже, в macOS 10.14 Mojave, единственный способ создать NSImage
экземпляры, которые автоматически рисуют светлую и темную версию, - через каталоги ресурсов и +[NSImage imageNamed:]
.Тем не менее, мне нужно создавать динамические образы во время выполнения, и, кажется, нет способа сделать это без использования частного API.
Под капотом, похоже, было введено частное свойство _appearanceName
NSImageRep
, который каким-то образом используется для выбора правильного представления.Было бы просто создать NSImage
с представлениями изображений, которые имеют соответствующий набор _appearanceName
, но я бы хотел этого избежать.
Я нашел простой обходной путь (опубликован ниже), но это не таккажется, что работает правильно, когда внешний вид системы меняется (т.е. пользователь переключается со светлого на темный или наоборот) или когда используется в иерархиях представления, у которых свойство 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