文档章节

iOS程序框架设计之皮肤切换功能 (白天与夜间效果)

行走中的菜鸟
 行走中的菜鸟
发布于 2015/08/24 17:38
字数 1535
阅读 932
收藏 6

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中的核心代码如下:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//单例方法
+(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的核心代码如下:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//移除监听
-( 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{
     
}

        到目前,我们已经可以顺利接收到主题切换的通知,可是要所有子类都步伐一致的执行相同一个操作,我们可以通过一个协议来约定,这就是图中的主框架的protocol,这个协议中规定一个特定的方法,我们在父类中调用,子类中实现,当收到通知时,所有子类都将重新加载这个方法,如果我们将皮肤设置部分在这个方法中实现,那么正是我们想要的效果,所有皮肤设置都被重新加载了。协议如下:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
  *这里定义主题的风格
  */
typedef  enum  {
     dayTime=1, //白天
     nightTime //夜间
}YHTopicModel;
@protocol YHTopicProcotol <NSObject>
//所有可以更换主题的界面必须遵守这个协议调用并实现如下方法
//将视图中控件的颜色摄住部分全部放在这个方法中
@required
-( void )useYHTopicToCreatViewWithModel;

        这时,就剩下我们这套逻辑的最后一步了,我们只需要将控件的颜色设置写在子类的协议方法中,并且,这些设置的数据来源于model这个模型,整个体系就完成了,子类实现方法如下:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-( void )useYHTopicToCreatViewWithModel{
//获取到模型
     YHTopicColorManager * model = [YHTopicColorManager sharedTheSingletion];
     //加载模型数据
     [model getTopicModel];
     //进行设置
     self.view.backgroundColor = model.bgColor;
     _schoolLabel.textColor = model.textColor;
     _phoneLabel.textColor = model.textColor;
     _secertLabel.textColor = model.textColor;
     _reWriteSecretLabel.textColor = model.textColor;
     _questionLabel.textColor = model.textColor;
     _answerLabel.textColor = model.textColor;
     _registBtn.backgroundColor = model.btnColor;
     [_registBtn setTitleColor:model.btnTextColor forState:UIControlStateNormal];
     
}

我简单写了一些界面,不论任何地方切换皮肤,所有界面效果都会改变:

切换夜间模式前:

                                   

开启夜间模式后:

                       

三、补充

        自己的思路实现更换主题的一种方法,真诚的想与志同道合的朋友交流开发经验,如果你想批评,点拨,交流或者是借鉴我的代码,Q316045346随时欢迎。



本文转载自:http://my.oschina.net/u/2340880/blog/495670

行走中的菜鸟
粉丝 1
博文 10
码字总数 1914
作品 0
海淀
程序员
私信 提问
iOS程序框架设计之皮肤切换功能

iOS程序框架设计之皮肤切换功能 一、引言 移动应用的开发中,有时我们会需要例如更换皮肤此类的功能,andorid采用xml配置UI的方式,这个问题或许还容易解决些,iOS的主要UI逻辑则是在代码中控...

珲少
2015/08/21
11.6K
15
iOS高仿QQ录音、智能语音诗歌、高仿微信图片浏览源码

iOS精选源码 好看实用的日期时间选择器--CCTimePicker 高仿QQ录音功能 QQ侧滑抽屉效果 MMActionSheet介绍(自定义的类似于微信的UIActionSheet弹出框组件) 智能语音查询诗歌 仿课程表表格效果...

sunnyaigd
2017/10/25
14
0
GitHub 上排名前 100 的 Objective-C 项目简介

主要对当前 GitHub 排名前 100 的项目做一个简单的简介, 方便初学者快速了解到当前 Objective-C 在 GitHub 的情况. 若有任何疑问可通过微博@李锦发联系我 项目名称 项目信息 1. AFNetworkin...

oschina
2015/04/11
33.9K
29
iOS 7 主要功能特性一览

在苹果WWDC 2013 上 iOS 7的发布带来了几大亮点: 首先全新的设计,iOS 从扁平化的设计开始与全球都在大抄袭苹果设计的浪潮说拜拜,内置应用程序全新icon 带来焕然一新的感受。 通知中心与多...

oschina
2013/06/11
4.1K
23
iOS Sprite Kit教程之编写程序以及Xcode的介绍

iOS Sprite Kit教程之编写程序以及Xcode的介绍 Xcode界面介绍 一个Xcode项目由很多的文件组成,例如代码文件、资源文件等。Xcode会帮助开发者对这些文件进行管理。所以,Xcode的界面也比较复...

大学霸
2015/07/23
281
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 我,小小编辑,食人族酋长

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享娃娃的单曲《飘洋过海来看你》: #今日歌曲推荐# 《飘洋过海来看你》- 娃娃 手机党少年们想听歌,请使劲儿戳(这里) @宇辰OSC...

小小编辑
今天
628
10
MongoDB系列-- SpringBoot 中对 MongoDB 的 基本操作

SpringBoot 中对 MongoDB 的 基本操作 Database 库的创建 首先 在MongoDB 操作客户端 Robo 3T 中 创建数据库: 增加用户User: 创建 Collections 集合(类似mysql 中的 表): 后面我们大部分都...

TcWong
今天
32
0
spring cloud

一、从面试题入手 1.1、什么事微服务 1.2、微服务之间如何独立通讯的 1.3、springCloud和Dubbo有哪些区别 1.通信机制:DUbbo基于RPC远程过程调用;微服务cloud基于http restFUL API 1.4、spr...

榴莲黑芝麻糊
今天
19
0
Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
昨天
56
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
昨天
60
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部