我使用NSDrawNinePartImage()
绘制可伸缩控件。由于这当然需要九个单独的图像来绘制部分(加上一些额外的部分),我有一个目录,其中包含top-left.png
和top-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作为我的图像编辑器,上次我检查时,它并没有真正理解那样的复合图像格式。
答案 0 :(得分:0)
简单的答案是使用TIFF,您的担忧是错误的。在Xcode中设置项目首选项“Combine High Resolution Artwork”并继续像现在一样使用Acorn生成两个PNG。在构建期间,Xcode会将这两个PNG组合成一个TIFF并将其存储在您的包中。
答案 1 :(得分: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;
}
答案 2 :(得分: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文件)。但它让您无需手动选择图像分辨率(这也需要您监听后备存储更改)。