iOS APP主题动态切换

作者: JohnnyB0Y | 来源:发表于2019-08-04 23:37 被阅读0次

前言:

迫于部门周会要做主持,得拿出点什么东西分享。一时间也想不到分享些什么好。
想想自己从未做过 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;

相关文章

网友评论

    本文标题:iOS APP主题动态切换

    本文链接:https://www.haomeiwen.com/subject/aqjudctx.html