我有一个包含多个目标的iOS应用。每个目标都有自己的.xcassets,其中包含特定于该目标的图像,我还有一个基础.xcassets文件夹,其中包含所有目标之间共享的图像。
基本.xcassets和目标.xcassets文件夹可能具有相同文件名的图像,但它们是不同的图像。当应用程序运行时,我希望Xcode使用目标.xcassets文件夹中的图像,而不是基本.xcassets文件夹中的图像。现在,当我在每个具有相同文件名的.xcassets文件夹中有两个不同的图像时,我收到编译器警告。当我运行应用程序时,它使用基本.xcassets文件夹中的图像。
有谁知道如何解决这个问题?我正在考虑编写某种shell脚本,但我想知道是否有更简单的方法。
答案 0 :(得分:1)
不要为base vs target使用相同的图像名称。它们之间的名称应该不同。我还特意写了一篇关于这个多目标资产问题的blog post。
答案 1 :(得分:0)
我在白标应用结构中有这个要求。基础应用程序具有完整的资产目录,每个特定目标可能会覆盖一些资源。我最终调配UIImage方法来寻找一个重写的前缀。每个目标都应该将该前缀添加到它要覆盖的资源名称中。从代码或IB加载图像时,如果存在,则调配将加载被覆盖的版本。
看起来像这样:
#import <JRSwizzle.h>
static NSString *_xcassetsOverridePrefix = @"override_";
static inline NSString* overridenName(NSString *name) {
return [_xcassetsOverridePrefix stringByAppendingString:name];
}
@implementation UIImage (OverrideableXCAssets)
+(void)load {
NSError *error;
if (![self jr_swizzleClassMethod:@selector(imageNamed:) withClassMethod:@selector(imageNamedReplacement:) error:&error]) {
NSLog(@"Error swizzling UIImage imageNamed: %@", [error localizedDescription]);
}
if (![self jr_swizzleClassMethod:@selector(imageNamed:inBundle:compatibleWithTraitCollection:) withClassMethod:@selector(imageNamedReplacement:inBundle:compatibleWithTraitCollection:) error:&error]) {
NSLog(@"Error swizzling UIImage imageNamed: %@", [error localizedDescription]);
}
}
+ (UIImage*)imageNamedReplacement:(NSString *)name {
UIImage *image = [self imageNamedReplacement:overridenName(name)];
if (!image) {
image = [self imageNamedReplacement:name];
}
return image;
}
+ (UIImage*)imageNamedReplacement:(NSString *)name inBundle:(NSBundle *)bundle compatibleWithTraitCollection:(UITraitCollection *)traitCollection {
UIImage *image = [self imageNamedReplacement:overridenName(name) inBundle:bundle compatibleWithTraitCollection:traitCollection];
if (!image) {
image = [self imageNamedReplacement:name inBundle:bundle compatibleWithTraitCollection:traitCollection];
}
return image;
}