2

NSDrawNinePartImage()用来绘制一个可拉伸的控件。由于这当然需要九个单独的图像来绘制零件(加上一些在其上绘制的额外内容),所以我有一个目录,其中包含top-left.pngtop-left@2x.png. 我将此目录作为文件夹引用包含在我的应用程序包中。

不幸的是,即使您在名称中加上斜线,通常的图像加载 API 似乎也不支持子目录-[NSImage imageNamed:]-[NSBundle imageForResource:]相反,我使用这种方法加载图像:

- (NSImage*)popoverImage:(NSString*)name {
    NSURL * url = [[NSBundle bundleForClass:self.class] URLForResource:name withExtension:@"png" subdirectory:@"popover"];
    return [[NSImage alloc] initWithContentsOfURL:url];
}

这适用于普通显示器,但它忽略了视网膜显示器的 2x 图像。我怎样才能让它也加载视网膜图像?有没有比分别加载两个代表并手动组合它们更好的方法?我宁愿不使用 TIFF 作为这些资源的源文件,因为我使用 Acorn 作为我的图像编辑器,而上次我检查时,它并不能很好地理解这样的复合图像格式。

4

3 回答 3

0

简单的答案是使用 TIFF,您的担心是错误的。在 Xcode 中,设置项目首选项“Combine High Resolution Artwork”,并像现在一样继续使用 Acorn 生成两个 PNG。在构建期间,Xcode 会将这两个 PNG 组合成一个 TIFF,并将其存储在您的包中。

于 2013-05-10T20:35:04.563 回答
0

我最终咬紧牙关,在运行时手动组合图像。我通过在 NSImage 上的一个类别中添加此方法,然后使用它代替-initWithContentsOfURL:

- (id)initRetinaImageWithContentsOfURL:(NSURL *)url {
    if((self = [self initWithContentsOfURL:url])) {
        NSURL * baseURL = url.URLByDeletingLastPathComponent;
        NSString * baseName = url.lastPathComponent.stringByDeletingPathExtension;
        NSString * extension = url.lastPathComponent.pathExtension;

        NSString * retinaBaseName = [NSString stringWithFormat:@"%@@2x", baseName];
        NSURL * retinaURL = [baseURL URLByAppendingPathComponent:[retinaBaseName stringByAppendingPathExtension:extension]];

        if([retinaURL checkResourceIsReachableAndReturnError:NULL]) {
            NSData * data = [[NSData alloc] initWithContentsOfURL:retinaURL];
            NSBitmapImageRep * rep = [[NSBitmapImageRep alloc] initWithData:data];

            rep.size = self.size;
            [self addRepresentation:rep];
        }
    }

    return self;
}
于 2013-05-12T02:16:48.810 回答
0

这就是我所做的:

NSArray *paths = [NSBundle.mainBundle pathsForResourcesOfType: @"icns" inDirectory: @"Collections/1"];

for (NSString *path in paths) {
    NSString *fileName = [[path lastPathComponent] stringByDeletingPathExtension];
    NSImage  *image = [[NSImage alloc] initWithContentsOfFile: path];
    image.name = fileName;
    [iconCollectionController addObject: @{@"icon": image}];
}

但正如 CRD 已经指出的那样,您需要合并您的作品(作为 tiff 或 icns 文件)。但它使您无需手动选择图像分辨率(这也需要您聆听后备存储更改)。

于 2013-05-12T16:26:50.420 回答