6

似乎在 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
4

1 回答 1

4

嗯,原来问题中发布的代码工作得很好!绘图处理程序实际上在适当的时候调用的,并且确实处理了所有的外观情况。

但是,我有缩放和缓存这些图像的代码,它仍然使用古老[image lockFocus]; … [image unlockFocus];的图像绘制方式,而不是使用+[NSImage imageWithSize:flipped:drawingHandler:].

于 2018-10-17T08:16:11.710 回答