1

I need to create an application that should have several themes. It means that for each theme we use different set of images. The theme should be changed without full reload of all view controllers (just change the images). The themes could be added via In app purchases so they should not be hardcoded.

I also want to use Interface Builder to create my views.

Question: what is the best way to do that?

3 Answers3

0

I would suggest the approach that I detail in my answer here:

Is there a simple way to set a default font for the whole app?

You could have view controllers in your app ask a ThemeApplicator class to style them when necessary. It would do this by setting the correct background image, that sort of thing. You can still use IB to build your views; just don't set a background in IB (or set a default background). The key is that you programmatically update the background later.

Community
  • 1
  • 1
occulus
  • 16,959
  • 6
  • 53
  • 76
0

On MyAppNotificationUIThemeChanged every controller has to retrieve and set images for every UIImageView in it's main view. I can think of 2 approaches for doing this:

1) Brute force. Something like this:

self.imageView1.image = [self currentThemeImage:@"someController_image1.png"];
self.imageView2.image = [self currentThemeImage:@"someController_image2.png"];

2) Automated approach.

NSArray *imageViews = [self fetchAllImageViews];
foreach (UIImageView *iv in imageViews) {
  iv.image = [self currentThemeImageForTag:iv.tag];
}

where currentThemeImageForTag: is something like this:

- (UIImage*)currentUIThemeImageForTag:(NSUInteger)imageTag {
  return [self currentUIThemeImage:[NSString stringWithFormat:@"%@_%u.png", NSStringFromClass([self class]), imageTag]];
}

I also suggest to use NSBundle to package theme images and other resources.

Update:

I chose NSBundle only because of it's cool methods like pathForResource:ofType: and such and also ability to support localization. You can create bundle with XCode (just look under Mac OS X -> Framework&Library section in new project dialog). Put your images in Resources, remove liks to any frameworks (there is no code anyway), build and that's it. In your app load bundle with [NSBundle bundleWithPath:pathToDownloadedBundle]. Beware though: I don't know if Apple allows to download bundles and use it's content in app. All I can guarantee is that it works on simulator.

hoha
  • 4,418
  • 17
  • 15
  • Thanks, this is the exact thing I was thinking about –  Mar 04 '11 at 12:32
  • Can you explain how to use NSBundle to package my resources? –  Mar 04 '11 at 12:33
  • I don't think it's wise to tie image names to actual class names in the source code. Plus, what if he wants the same background on five different UIs? Some level of indirection might be useful. – occulus Mar 04 '11 at 15:53
  • @occulus, if each controller has some screenName property actual class name can be changed during app lifecycle without breaking themes. "what if he wants the same background on five different UIs" - if he wants same iage for some particular view on all UIs we just mark it with special tag (like 0, or <128, whatever) and filter out such views during customization, but if he wants to reuse backgrounds for some themes - there is no simple solution. Some global pool of downloaded images is required and strategy to determine what subset of this theme images we lack locally etc. – hoha Mar 04 '11 at 16:38
0

Look at Three20 project, especially at Three20Style.

zrzka
  • 20,249
  • 5
  • 47
  • 73