Как вручную создать динамические (темные / светлые) экземпляры NSImage?
Кажется, в 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
1 ответ
Выяснилось, что код, указанный в вопросе, работает просто отлично! Обработчик рисования фактически вызывается в подходящее время и обрабатывает все ситуации внешнего вида.
Тем не менее, у меня был код, который масштабировал и кэшировал эти изображения, и он все еще использовал древние [image lockFocus]; … [image unlockFocus];
способ рисования изображений вместо использования +[NSImage imageWithSize:flipped:drawingHandler:]
,