iOS APP主题动态切换

前言:

迫于部门周会要做主持,得拿出点什么东西分享。一时间也想不到分享些什么好。
想想自己从未做过 iOS 主题动态切换这个需求,又觉得这个需求好像蛮有挑战的。
所以就有了今天这个文章。😁😁😁

思路是这样的:

第一步

首先考虑的是输入方式,既我们怎样配置主题文件?
我想到了3种方式:
1)直接代码组织;
先来直接工程中用类来配置主题包。
我是采用通过 AGThemePack 主题包类,派生子类的方式来做,每一个子类就是独立的主题包。

2)文件,如JSON 文件或 .plist 文件;
那么对于文件,这个也好处理,同样派生 AGThemePack 的子类,然后在内部加载文件并解析数据就好了。

3)网络数据;
对于网络数据也是同上,派生 AGThemePack 的子类,在内部解析网络数据。

第二步

接着考虑如何输出,既我们的主题更新时,如何让界面响应?
对这种需求用观察者的方式做再好不过了。
相对于通知这种观察者,我选择了Block 这种方式。
而且用NSMapTable 还可以做到视图销毁后,自动移除Block。

第三步

我们把输入输出都考虑好后,就要考虑数据的流动了。
这一步要确定使用哪一种数据结构,和协助类的组织方式。
在这里,曾考虑过使用一个 Task 类来管理 Block 的生命周期,后来简化掉了。
所以最终是使用 AGThemePackBox 主题箱的概念来管理所有的主题包,每个主题包类注册到主题箱中。
AGThemePackBox 就相当于一个主题容器和主题状态管理器。

那么观察者是谁呢?是 AGThemeManager (很俗的名字😂😂😂)。
它内部有个容器管理所有订阅者的Block,当订阅者销毁后,就丢弃对应的Block。
当主题更换时,调用所有订阅者的Block,以达到界面刷新。

结尾:(总结最近悟出的方法论)
  • 首先思考:输入与输出的方式与效果;
  • 然后思考:从输入到输出的数据流动与处理方式;
  • 接着思考:这种数据流动与处理方式对应使用哪种数据结构好;
  • 最后,把以上的过程方式通过设计各种类与数据结构连结起来。

使用方式:AGThemeManager @GitHub

 1,通过派生子类生成主题包,有3中方式生成主题包
 - 工程中
 派生 AGThemePack 的子类,重写初始化方法 -initWithPackName: 并配置主题元素;
 每个子类就是不同的主题包
 
 - 本地文件
 派生 AGThemePack 的子类,重写初始化方法 -initWithContentOfFile: 并配置主题元素;
 
 - 网络
 派生 AGThemePack 的子类,重写初始化方法 -initWithThemePackData: 并配置主题元素;

// 参考 项目中 Demo/CustomTheme 下的自定义类
 

 2,在UI类中使用主题包
 - 调用 -ag_setupAndExecuteThemeUsingBlock: 方法,添加设置Block并执行;
 - 需要注意的是,在Block 中注意循环引用问题;
 - 其实不需要手动移除设置Block,在类dealloc 后,会自动移除Block;

// 根据主题,配置好并执行
__weak typeof(self) weakSelf = self;
[self ag_setupAndExecuteThemeUsingBlock:^(NSString * _Nonnull theme, AGThemePack * _Nonnull pack) {
    __strong typeof(weakSelf) self = weakSelf;
    if ( nil == self ) return;
    // ...
    NSString *imageName = pack[kAGThemePackHomeCellIconImageName];
    self.imageView.image = [UIImage imageNamed:imageName];
    self.textLabel.font = pack[kAGThemePackHomeCellContentTextFont];
    self.textLabel.textColor = pack[kAGThemePackHomeCellContentTextColor];
}];
 
 
 3,初始化配置
 - 在 AppDelegate 中,初始化视图界面之前配置好要使用的主题;
 // 配置主题
 AGThemePackBox *themePackBox = [AGThemePackBox newWithCurrentTheme:kAGOrangeThemePack];
 [themePackBox ag_registerThemePack:[AGOrangeThemePack newWithPackName:kAGOrangeThemePack]];
 [themePackBox ag_registerThemePack:[AGPurpleThemePack newWithPackName:kAGPurpleThemePack]];
 [themePackBox ag_registerThemePack:[AGBlueThemePack newWithPackName:kAGBlueThemePack]];
 [AGThemeManager sharedInstance].themePackBox = themePackBox;
 // 打开调试日志
 [AGThemeManager sharedInstance].openLog = YES;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,144评论 1 32
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,820评论 0 10
  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,252评论 1 23
  • 姓名夏钢,无锡夏利达公司 【日精进打卡第15天】 【知~学习】 《六项精进》2遍共2遍 《大学》1遍共1遍 •••...
    Atun0219阅读 117评论 0 0
  • 1、划小单元让企业灵活高效。 2、独立核算,让每个部门盈利。 3、内部交易,让员工被动变主动 4、经营会计,让员工...
    萍空间阅读 448评论 0 0