这篇文章将为大家详细讲解有关iOS如何实现换肤功能的简单处理框架,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
效果如下:
演示代码:https://gitee.com/dhar/iosdemos/tree/master/YTThemeManagerDemo
<强>颜色配置强>
因为涉及到多种配置,所以以代码的方式定义颜色实践和维护的难度是比较高的,一种合适的方案是——颜色的配置是通过配置文件的形式进行导入的。配置文件会经过转换步骤,最终形成代码层级的配置,以全局的方式提供给各个模块使用,这里会涉及到一个颜色管理者的概念,一般地这回事一个单例对象,提供全局访问的接口。同一个应用程序中在不同的模块中保存不同的主题颜色配置,在不同的层级中也可以存在不同的主题颜色配置,因为涉及到层级间的配置差异,所以颜色的配置需要引入一个等级的概念,一般地较高层级颜色的配置等级是高于较低层级的,存在相同的配置较高层级的配置会覆盖较低层级的配置。
我们采用的颜色配置的文件形如下面所示,为什么是在一个json文件的colorkey下面呢,是为了考虑到未来的扩展性,如果不同的主题会涉及到一些尺寸值的差异化,我们可以添加dimensionskey进行扩展配置。
{ ,“color": { ,“Black_A":“323232”, ,“Black_AT":“323232”, ,“Black_B":“888888”, ,“Black_BT":“888888”, ,“White_A":“ffffff" ,“White_AT":“ffffff" ,“White_AN":“ffffff" ,“Red_A":“ff87a0" ,“Red_AT":“ff87a0" ,“Red_B":“ff5073" ,“Red_BT":“ff5073" ,“Colour_A":“377 ce4" ,“Colour_B":“6 aaafa" ,“Colour_C":“ff8c55" ,“Colour_D":“ffa200" ,“Colour_E":“c4a27a" ,} }
有了以上的配置,颜色配置的工作主要就是解析该配置文件,把配置保存在一个单例对象中即可,这部分主要的步骤如下:
- <李>
配置文件类表根据等级排序
李> <李>获取每个配置文件中的配置,进行保存
李> <李>通知外部主题颜色配置发生改变
李>对应的代码如下,这里有个需要注意的地方是,加载配置文件的时候使用了文件读写锁进行读写的锁定操作,防止读脏数据的发生,直到配置文件加载完成,释放读写锁,这时读进程可以继续。
安康;(void) loadConfigWithFileName: (NSString *) fileName 水平:(NSInteger) level { ,if (fileName.length ==, 0), { ,返回; ,} , ,pthread_rwlock_wrlock(及_rwlock); ,__block BOOL finded =,没有; ,[self.configFileQueue enumerateObjectsUsingBlock: ^ (YTThemeConfigFile * _Nonnull  obj, NSUInteger idx,, BOOL * _Nonnull 停止),{ ,if ([obj.fileName isEqualToString:文件名]),{ 时间=finded 才能;是的;=*才能stop 是的; ,} ,}]; 发现,if (!), { ,//新增配置文件 ,YTThemeConfigFile * file =, [[YTThemeConfigFile alloc], init);=,,file.fileName 文件名;=,file.level 水平; ,(self.configFileQueue addObject:文件); ,//优先级排序 ,(self.configFileQueue sortUsingComparator: ^ NSComparisonResult (YTThemeConfigFile * _Nonnull 其中obj1, YTThemeConfigFile * _Nonnull methoda), { if 才能;(obj1.level 祝辞,obj2.level), { return 才能;NSOrderedDescending; ,,} return 才能;NSOrderedAscending; ,}]; ,(self setupConfigFilesContainDefault:是的); ,} ,pthread_rwlock_unlock(及_rwlock); } 安康;(空白)setupConfigFilesContainDefault:(BOOL) containDefault { ,NSMutableDictionary * defaultColorDict =, nil,, * currentColorDict =,零; , ,//加载默认配置 ,if (containDefault), {=,defaultColorDict [NSMutableDictionary 字典); ,[self loadConfigDataWithColorMap: defaultColorDict valueMap: nil isDefault:是的); ,=,,self.defaultColorMap  defaultColorDict; ,} , ,//加载主题配置 ,if (_themePath.length 祝辞,0),{=,currentColorDict [NSMutableDictionary 字典); ,[self loadConfigDataWithColorMap: currentColorDict valueMap: nil isDefault:没有); ,=,,self.currentColorMap  currentColorDict; ,} , ,//发送主体颜色变更通知 ,[self notifyThemeDidChange]; } 安康;(空白)notifyThemeDidChange { ,NSArray * allActionObjects =, self.actionMap.objectEnumerator.allObjects; ,for (YTThemeAction * action  allActionObjects拷贝),{ ,[action notifyThemeDidChange]; ,} } 安康;(空白)loadConfigDataWithColorMap:(NSMutableDictionary *) colorMap valueMap: (NSMutableDictionary *) valueMap isDefault: (BOOL) isDefault {//大敌;每一次新增一个配置文件,所有配置文件都得重新计算一次,这里有很多重复多余的工作 ,[self.configFileQueue enumerateObjectsUsingBlock: ^ (YTThemeConfigFile * _Nonnull  obj, NSUInteger idx,, BOOL * _Nonnull 停止),{ ,NSDictionary * dict =,零; ,if (isDefault), { 时间=dict 才能;obj.defaultDict; ,}else { 时间=dict 才能;obj.currentDict; ,} ,if (dict.count 祝辞,0),{ null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null nulliOS如何实现换肤功能的简单处理框架