Вопрос

I have an iOS app with multiple targets. Each target has its own .xcassets that holds images specific to that target, I also have a base .xcassets folder which holds images that are shared between all the targets.

It is possible for the base .xcassets and the target .xcassets folder to have an image with the same file name, but they are different images. When the app runs, I would like Xcode to use the image from the targets .xcassets folder, instead of the image from the base .xcassets folder. Right now, when I have two different images in each of the .xcassets folders with the same file name, I get a compiler warning. When I run the app, it uses the image from the base .xcassets folder.

Does anyone know how to solve this issue? I am thinking of writing some kind of shell script, but I wanted to know if there was a simpler way.

Это было полезно?

Решение

Don't use the same image name for base vs target. The names should be different between them. I also wrote up a blog post specifically about this multi-target assets issue.

Другие советы

I have that requirement in a white-label app structure. The base app has a complete asset catalog, and each specific target may override a few resources. I ended up swizzling UIImage methods to look for a overriding prefix. Each target should add that prefix to the resource names it wants to override. When loading the image from code or IB, the swizzling will load the overridden version if it exists.

It looks like this:

#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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top