IOS暗黑模式 - 主题切换

    IOS 13 发布月余,一直未适配暗黑模式,只是简单地设置不支持暗黑模式。前几天传言再不适配暗黑,苹果就下架WX,着实一惊。细细查看一番,发现还没这么严苛,但是无风不起浪,既然提起了,那就做下主题功能。顺带着把暗黑模式也给包含在内。

    之前通过通知,在各个页面接受通知,改变显示,一般就是颜色、图片、字号等,全部工作绑在了页面内部。  

    查阅了些主题实现的方式,有个BD的想法感觉实现简单,就是颜色、图片、字号等对象分别绑定属性标志,在设置颜色、图片、字号的时候,设置绑定属性(可以直接把颜色、图片、字号值设为属性值,便于直接切换时操作)。同时,在持有这些对象的控件添加展示的时候收集起来。这样,在切换主题的时机(可能手动、或者手机系统暗黑模式切换),从收集的控件里面,判断控件持有对象的绑定属性是否存在。若存在,那么就是需要切换主题操作的控件,根据属性值(颜色、图片、字号),及当前要切换的主题,从本地主题库里取出对应的主题属性值,赋值给取出的控件,就完成了主题的切换。

梳理下,要分几步整理。

1、主题库的生成(创建json文件或者约定的格式)

    像Android的话,由于自带的生成字号、颜色等xml文件, 主题切换做起来就顺手多了,直接把这些xml文件复制下,里面的属性值(font,color等)修改下就变成了另一套主题,切换主题就是切换xml文件。

    ios 的话,把颜色、字体等也像Android那样,放json文件里(后期从服务器下载下来,转化成本地json文件),切换主题的话,直接切换json文件就好了,根据主题修改下获取文件路径。看起来,也顺手多了。

2、系统对象的属性绑定(分类实现)

给image、font、color对象分别绑定图片名称、字号大小、颜色值属性。利用runtime机制,在UIColor、UIFont、UIImage分类里实现setter、getter方法,分别添加分类方法,例如在实现里设置绑定属性值

@property(strong,non)imageName;

+(UIImage)imageWithKey:(NSString*)key {

self.imageName = key;//设置image对象imageName属性值

return [self  setImageWith:key : currentTheme];//根据当前主题及key值获取新主题的控件图片,在实现里获取设置的主题,一般存本地(获取当前设置的主题,找到对应json文件,再由key值取到属性值,从而赋值给对象)

}

在对color绑定的属性的时候遇到了些麻烦,但是问题不大,对持有color属性的对象绑定属性也是一样可以实现效果的。

3、切换主题的控件收集(分类实现)

页面被添加到父容器上时,执行didmovetosuperview,此时,收集控件。就是在分类里didmovetosuperview方法里实现添加操作。同时,对ios13来说,暗黑模式切换会在view,controlle的traitdidchange...里面操作。分类里在traitdidchange...里判断暗黑模式切换,执行刷新主题的操作。

4、刷新主题、切换主题(分类实现、主题管理类实现)

如果手机系统切换暗黑模式变换,那么在分类里根据模式自动切换刷新,根据收集到的控件,遍历查看它们的color、image、font对象的绑定属性imageName等是否存在.如存在,那么就根据绑定属性imageName重新设置下,

例如:v.image = [UIImage imageWithKey:v.imageName];具体各个页面的其他对象用法也是类似这样的。

如果多主题手动切换,也是类似的,主题管理类里面,获取需要切换的控件,根据控件持有对象的绑定属性重新设置,就完成了主题切换。

5、使用主题功能

使用的话,导入分类、主题管理类,调用分类方法例如+(UIImage *)imageWithKey:(NSString *)key就可以了,当然定义个宏XXXIMAGE(KEY,PARA)再调用也很顺手。

总结下,就是使用分类,runtime绑定属性,收集持有color、image、font的对象(控件),根据绑定属性重新设置color、image、font.这样,就完成了主题的切换。还是很简单易实现的。

git上不去了,有时间的话,下次,结合代码demo,再补充下。

你可能感兴趣的:(IOS暗黑模式 - 主题切换)