2

I am creating an application that will be able to switch its UI theme to different colors including icons. I plan to have different sets of icons that will be stored on different folders(green folder, yellow folder, etc). The name of the icons will be the same across all the folders the only thing that will change is its color.

Here is the code that i am currently using when setting the images for buttons and icons

[menuBtn setBackgroundImage:[UIImage imageNamed:@"menuBtn.png"] forState:UIControlStateNormal]

For example if the user selected yellow as the app theme. internally there will be some kind of switch that will choose a path for the image ex. the code above will evaluate to something like "yellow/menuBtn.png" when user selects yellow or "green/menuBtn.png" when the user selects green. Is this possible?

John Titor
  • 77
  • 1
  • 7
  • Very similar question here: http://stackoverflow.com/questions/7733565/ios-how-to-use-images-in-custom-bundle-in-interface-builder – allprog Aug 08 '13 at 10:43

2 Answers2

2

Sure, you can do [UIImage imageNamed:[NSString stringWithFormat:@"%@/menuBtn.png", colourVar]] and just set colourVar prior to setting the image.

Nicholas Smith
  • 11,642
  • 6
  • 37
  • 55
  • Hi, is that the only way? Because i have lots of images and codes that will be modified if i will use this approach. I was thinking that there may be some internal switch where i can specify the default location. that way the "homeBtn.png" that i specified in the code can be point to different locations without modifying the code. – John Titor Aug 08 '13 at 11:24
0

if you don't want to modify existing code, you can write a category, which will replace at runtime name of images, at initial stage it can be something like this:

@implementation UIImage (replacementImage)

+ (void) load {
    Method fontWithName_size_ = class_getClassMethod([UIImage class], @selector(imageNamed:));
    Method replacementFontWithName_size_ = class_getClassMethod([UIImage class], @selector(replacement_imageNamed:));

    if (fontWithName_size_ && replacementFontWithName_size_ && strcmp(method_getTypeEncoding(fontWithName_size_), method_getTypeEncoding(replacementFontWithName_size_)) == 0)
        method_exchangeImplementations(fontWithName_size_, replacementFontWithName_size_);
}

+ (UIImage *)replacement_imageNamed:(NSString *)name {
    NSString *currentLocation = #YOUR_CURRENT_IMAGES_LOCATION#;
    NSString *replacementImageName = [currentLocation stringByAppendingPathComponent:name];
    return [self replacement_imageNamed:replacementImageName];
}

@end

But it replace only implementation of method imageNamed, this may be insufficient and you will need to replace some other methods. I don't tested this, so it may be necessary to add some adjustments. Also it would be useful to check is image exists in current location, if not then search it in another.

With such approach images setuped in IB also will be replaced.

Mikhail
  • 4,271
  • 3
  • 27
  • 39