如何在iOS应用中切换皮肤(或设计主题)?

时间:2011-10-29 16:03:52

标签: iphone ios themes skin

我想让我的iPhone应用程序能够在皮肤之间切换(或设计主题,或外观和感觉,如木头,金属,地球颜色,男人,女孩等......)。

我将准备一些包含按钮和背景,声音和文本颜色图像的皮肤集,并让用户根据应用程序设置决定他们想要使用哪一组皮肤。

实施此操作的最佳做​​法是什么?

条件是:

  • 我想使用Interface Builder
  • 我需要支持iOS 3.1.3及更高版本
  • 我想从互联网上下载皮肤集(我不能捆绑应用程序中的所有皮肤,因为一组皮肤需要大量图像,如果我这样做,应用程序文件大小可能变得很大。 ..我也不想硬编码任何有关特定皮肤的信息。)
  • 如果自定义皮肤不包含一个或一些元素(例如图像或声音文件),我希望它使用默认皮肤集中的缺失元素。
  • 我不想为每个皮肤创建Nib文件。一个屏幕的Nib文件应该是主软件包中唯一的一个,以便于维护。

我正在考虑在我的应用程序中创建所有UIViewControllers的超类并覆盖它加载Nib文件的部分,而不是从主bundle加载,从Document目录中保存的皮肤加载资源...但我不知道怎么做... Nib加载方法的默认行为总是从主包中加载资源,并且在阅读后会丢失有关资源文件名的信息... :(

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

我不确定最佳做法..但是,如果你的应用程序不够大,那么结构良好的plist就是你的朋友。

最初,您可以选择:金属主题。以下内容应该成立:

您要么拥有单身人士ThemeManager,要么只在适当的情况下将NSDictionary贴在您的单身人士身上。

ThemeManager背后的重点是资产和主题之间的映射..

一些示例代码(直接在SOF上编写..不要介意语法错误):

#define kThemeMap(__x__) [[ThemeManager sharedManager] assetForCurrentTheme:__x__]

...

-(void)doUselessStuff {
    UIImage* backgroundImage = [UIImage imageNamed:kThemeMap(@"FirstViewBG")];

    ...

}

//in the ThemeManager:
//returns the appropriate name of the asset based on current theme
-(NSString*)assetForCurrentTheme:(NSString*)asset {
    //_currentTheme is an NSDictionary initialized from a plist. Plist can be downloaded, too.
    NSString* newAsset = [_currentTheme objectForKey:asset];
    if(newAsset == nil) {
        newAsset = [_defaultTheme objectForKey:asset];
    }
    return asset;
}

//Let us assume the user selects Metal Theme somewhere .. Still coding ThemeManager:
-(void)selectedNewTheme:(NSString*)newTheme {
    //First, get the full path of the resource .. Either The main bundle, or documents directory or elsewhere..
    NSString* fullPath = ...;
    self.currentTheme = [NSDictionary dictionaryWithContentsOfFile:fullPath];
}

plist文件只是一个字符串,其中包含字符串到字符串的映射......如下所示:

//Default.plist
@"FirstViewBG"  : @"FirstViewBG_Default.png"
@"SecondViewBG" : @"SecondViewBG_Default.png"
@"WinSound"     : @"WinSound_Default.aiff"

//Metal.plist
@"FirstViewBG"  : @"FirstViewBG_Metal.png"
@"SecondViewBG" : @"SecondViewBG_Metal.png"
@"WinSound"     : @"WinSound_Metal.aiff"

或者,你可以保存后缀,如果这对你来说足够好了..但是,它需要字符串操作,通过切片扩展 - >添加后缀 - >添加扩展名..

或者也许把它作为前缀?

答案 1 :(得分:0)

您可以使用分类的imageNamed:在UIImage上进行分类,使用自定义imageNamed:而不是默认值。 在自定义方法中,按主题选择图像。