iOS程序框架设计之皮肤切换功能
一、引言
移动应用的开发中,有时我们会需要例如更换皮肤此类的功能,andorid采用xml配置UI的方式,这个问题或许还容易解决些,iOS的主要UI逻辑则是在代码中控制的,如果没有一个强大的框架方案,这个问题将变得非常棘手。网上也有很多诸如此类功能的优秀案例与框架,在这篇博客中,我与大家分享下我的解决方案,其中如果有不恰或者糟糕之处,希望与高人一起交流。
二、设计思路与框架
首先我的设计思路是采用通知的方式,原理可以如下理解为以下几步:
1、在系统的通知中心注册一个通知
2、所有需要更改皮肤功能的controller作为这个通知的监听者
3、设计一个皮肤的model类
4、将controller中有关皮肤设置的属性从model中取
5、在切换皮肤前更改皮肤model
6、发送更改皮肤的通知
上面的6个步骤是这整个框架的基本逻辑,框架无非是将这些逻辑进行优化与封装。下面这张图很烂,但是思路很清晰:
首先最上面是我设计的一个切换主题的manager,我这里的设计有个缺陷,我将manager和主题配置相关的model混合在了一起,写的时候简单了些,可这给框架的逻辑上带来了混乱,所以我在图中使用曲线和虚椭圆将其分离,manager来控制切换model的属性,我们在controller中取model的属性进行配置,这个manager的逻辑位置是交互时间与通知中心的桥梁。manager中的核心代码如下:
//单例方法
+(instancetype)sharedTheSingletion{
static YHTopicColorManager * sharedModel = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedModel = [[YHTopicColorManager alloc] init];
});
return sharedModel;
}
//这个方法应该分离在model中,从本地读取当前的主题模式,更改后我们只需要更改本地数据 然后重新调用这个方法即可
-(void)getTopicModel{
//从本地读取
int tp = [YHSASystemSettingManager sharedTheSingletion].topic;
if (tp==0) {
//默认为白天主题
tp=dayTime;
[YHSASystemSettingManager sharedTheSingletion].topic = tp;
}
switch (tp) {
//这里是我定义的一些枚举,拿白天和夜间模式示范
case dayTime://白天模式
{
//这里面定义一些白天模式下 控件的颜色属性 也可以定义其他
_navColor=[UIColor colorWithRed:10/255.0 green:85/255.0 blue:160/255.0 alpha:1];
_bgColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1];
_btnColor=[UIColor colorWithRed:10/255.0 green:85/255.0 blue:160/255.0 alpha:1];
_textColor=[UIColor colorWithRed:0 green:0 blue:0 alpha:1];
_btnTextColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1];
_navTextColor= [UIColor whiteColor];
}
break;
case nightTime://夜间模式
{
//这里面定义夜间模式下的相关控件的颜色属性
_navColor=[UIColor colorWithRed:10/255.0 green:85/255.0 blue:160/255.0 alpha:1];
_bgColor=[UIColor colorWithRed:0 green:0 blue:0 alpha:1];
_btnColor=[UIColor colorWithRed:10/255.0 green:85/255.0 blue:160/255.0 alpha:1];
_textColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1];
_btnTextColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1];
_navTextColor= [UIColor whiteColor];
}
break;
default:
break;
}
}
//发送更改主题的消息
+(void)postTopicChangeMessage{
[[NSNotificationCenter defaultCenter]postNotificationName:YHTopicChangeTopicNotication object:nil];
}
在manager调用通知中心发送通知后,我们要让所有需要改变主题的视图控制器都接收到通知,最简便的做法是,我们设计一个父类,让父类监听通知,所有需要有主题更改功能的控制器继承于它即可,这个father controller的核心代码如下:
//移除监听
-(void)dealloc{
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//添加监听主题更换的通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(useYHTopicToCreatViewWithModel) name:YHTopicChangeTopicNotication object:nil];
//协议中的方法,加载主题 一会再说
[self useYHTopicToCreatViewWithModel];
}
//子类实现如下方法
-(void)useYHTopicToCreatViewWithModel{
}