iOS开发之App主题切换完整解决方案(Swift版)

本篇博客就来介绍一下iOS App中主题切换的常规做法,当然本篇博客中只是提到了一种主题切换的方法,当然还有其他方法,在此就不做过多赘述了。本篇博客中所涉及的Demo完全使用Swift3.0编写完成,并使用iOS的NSNotification来触发主题切换的动作。本篇博客我们先对我们的主题系统进行设计,然后给出具体实现方式。当然在我们设计本篇博客所涉及的Demo时,我们要遵循“高内聚,低耦合”,“面向接口编程”,“便于维护与扩充”等特点。

本篇博客我们先看一下Demo的运行效果,然后给出设计方案已经对应的类图,然后再根据设计的类图给出相应的代码实现。

一、主题切换效果展示

先入为主,接下来我们先看一下本篇博客所涉及Demo的最终运行效果。为了看到整体主题切换的效果,所以我们添加了一个主页以及主页Push进去的子页面。另一个页面就是选择相应主题的页面,也就是下方你所看到的TabieView的列表页,该列表中提供了6种可选的主题,点击相应的主题即可切换到该主题上。

当然主题切换,意味着整个App的风格都得改变,所以当修改完主题后,主页以及其子页面的主题也得随之改变。具体效果如下gif图所示。当然Demo比较简单,但是麻雀虽小,五脏俱全,用来了解App的主题切换足以。当然有更好的实现方式,欢迎留言交流。

  

 二、设计主题切换功能的整体结构

看完效果后,接下来我们就进入了设计阶段。根据上述Demo的特点,我们先给出相应的类图,当然我们敲代码时要根据该类图进行实现。下方截图就是我们本篇博客主题切换工程的类图了。该类图中省略了一些细节,给出了核心的内容。接下来我们来详细的看一下下方这个类图的结构,如果下方的类图搞明白了,那么在下部分中看相应代码时,就会显得游刃有余了,因为我们的代码是按照下方的类图所实现的。只不过比下方类图更为详细。

接下来我们就来看一下类图的结构,我们就按照不同颜色的框逐一介绍,框中的内容算是一个模块。

  • 红色框:下方类图红色框中就是我们的主题协议ThemeProtocol以及遵循该协议的所有主题。当然,依据“面向接口”编程的规则,外部所依赖的不是所有的主题类,而是主题协议ThemeProtocol。也就是ThemeManager类依赖于ThemeProtocol。而所有的主题类通过工厂类或者工厂方法间接的与ThemeManager。因为鉴于Swift中的枚举中可以添加相应的计算属性以及方法,所以我们可以使用相应的主题枚举来充当这个工厂类,当然下方类图中没有给出,这个要看具体的代码实现。

  • 蓝色框:接下来我们就来看蓝色框,蓝色框中的SuperLabelClass是所有可以改变主题的Label的父类,也就是说在改变主题时,需要改变相应的Label就要继承该类。

  • 黑色框:该框中中则是SuperViewController及其子类,需要更换主题的VC都要继承自该基类。

  • 绿色框:绿框中则负责修改主题,其中根据Cell的类型来确定用户选择的是哪个主题。

  • ThemeManager: 该类以单例的形式存在,负责管理相应的主题,切换主题时,直接调用ThemeManager中的相应的方法即可。

上面只是简单的介绍一下类图,具体的还要看代码的实现。

  

三、主题以及主题管理者的实现

看完运行效果以及设计类图,接下来我们就来一下具体的代码实现本部分我们就来看一下相应的主题类以及主题管理者的代码实现。下方会先给出主题协议以及各个主题类的实现,然后再给出主题工厂方法以及主题管理者的实现。

1、主题协议的实现

下方就是我们定义的主题协议,所有主题都要遵循该协议。因为本篇博客的Demo在切换主题时只涉及到了三个元素,一个是背景色(backgroundColor),一个是标题的颜色(titleTextColor),在一个就是详情的颜色(detailTextColor)。所以在我们的主题协议中有三个只读的计算属性与之对应。具体如下所示:

  

2.各个主题的实现

接下来我们就要看看各个主题的实现了,我们就以红色主题(RedTheme)为例。RedTheme要遵循ThemeProtocol,并且实现协议中规定的方法。在RedTheme中每个计算属性都会返回当前主题所对应的属性。具体如下所示。当然其他主题与下方的RedTheme类似,只是每个计算属性返回的值不同。

  

上面在返回UIColor对象时,我们用到了UIColor.colorWithHex(十六进制数)。colorWithHex()是我们在UIColor的延展中添加的静态方法,该方法可以根据十六进制的RGB参数来初始化相应的UIColor对象。下方是该UIColor延展中的具体内容。下方代码的核心就是位操作的使用。

  

3.简单工厂的创建

主题协议已经主题类构建完毕后,接下来我们就该将这些主题进行打包输出了。 下方的代码段本质上就是主题类的简单工厂,因为Swift的枚举类型有很多好用的特性,所以我们使用了Swift的枚举来实现这些主题的简单工厂。代码结构比较简单,在此就不做过多赘述了。

  

4.主题管理者(ThemeManager)的创建

上面关于主题的基本工作已经做完,接下来我们就为这些主题来创建一个主题管理者ThemeManager。ThemeManager会根据用户需求从上面的主题工厂中取出相应的主题对象提供给用户,这也就是ThemeManager的职能所在。

下方就是我们主题管理者ThemeManager的具体实现代码,ThemeManager是以单例的姿态对外展现的。因为主题管理者在整个App运行时只需要一个,所以我们赋予了ThemeManager一个单例的身份与用户进行交流。单例实现完毕后,接着社一些便利方法,这些便利方法都是静态方法,便于用户直接使用。接着是一些ThemeManager的私有方法。

在ThemeManager的私有方法中,switcherTheme(themeType)是关键,该方法在收到修改主题的事件后,会发出修改主题的通知,而通知的内容就是将要进行修改的主题。那些可以修改主题的控件,在收到该通知的消息后,会根据通知内容修改其自身的主题。具体代码如下所示:

  

四、可更换主题的控件处理

主题以及主题管理者实现完毕,接下来就该使用了。在主题切换时,需要修改属性的控件我们需要进行处理,使其监听主题切换的通知,并根据通知内容修改控件的属性。在本部分我们就以SuperViewController为例。首先我们要将SuperViewController添加为主题切换的观察者,然后实现收到通知后的方法。在析构函数中,切记要移除观察者。具体代码如下所示。

  

五、调用ThemeManager更换主题

万事俱备只欠东风,接下来我们就要在恰当的地方调用ThemeManager的switcherTheme()的方法进行替换了。当然我们是在我们的Cell来处理的,因为每种cell都对应着主题的类型,下方就是Cell类型的枚举。CellTitleType中的themeType计算属性就对应着相应的主题类型,我们可以将该类型提供给ThemeManager,让后ThemeManager发出更改主题的通知。

  

下方就是调用ThemeManager的switcherTheme()方法来更换主题。

  

至此,本篇博客所涉及的主题切换的Demo就介绍完毕了,所涉及的Demo按照惯例,依然会在github上进行分享。下方就是Demo在github上分享地址。

代码分享地址:https://github.com/lizelu/CEThemeSwitcher

时间: 2024-11-04 21:36:32

iOS开发之App主题切换完整解决方案(Swift版)的相关文章

iOS开发之App间账号共享与SDK封装

App间的数据共享可以使用KeyChian来实现.本篇博客就实战一下呢.开门见山,本篇博客会封装一个登录用的SDK, 该登录SDK中包括登录.注册.忘记密码等功能,当然该SDK中包括这些功能的UI.数据验证等业务逻辑.网络请求.数据存储等等.当然此处的登录SDK是一个简化版的,真正的登录SDK比这个考虑的东西要多的多,如果在加上多个App进行登录账号的共享的话,那么考虑的东西就更为复杂了. 本篇博客就先封装一个LoginSDK, 让后将该SDK植入到两个App中(一个暂且叫做"App One&q

iOS开发之App启动原理

iOS程序的启动过程 程序启动的完整过程大致步骤如下: 1.main函数 2.UIApplicationMain * 创建UIApplication对象 * 创建UIApplication的delegate对象 3.delegate对象开始处理(监听)系统事件(没有storyboard) * 程序启动完毕的时候, 就会调用代理的application:didFinishLaunchingWithOptions:方法 * 在application:didFinishLaunchingWithOpt

iOS开发之APP上线

首先自我介绍一下,我是来自广州的iOS程序猿,工作有2年了,没有写过博客啥的.第一次想写点东西,记录下自己学到的东西和感悟.今天半夜里看了篇文章后,我也想自己写篇文章,虽然我也不知道我要写什么,怎么写....好吧,那就APP上线吧! APP 上线有两种途径: 一种是 Xcode->openDeveloperTool->applicationLoader,这种打开后登陆appleID就可以选取并且交付您的应用程序了.这种呢,我们交付之前首先要Xcode打包出来一个.ipa (打包的过程,其实百度

ios开发之APP升级的实现

直接上代码: /** * 检测软件是否需要升级 */ -(void)checkVersion { NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://itunes.apple.com/cn/lookup?id=%i",iFeverAPPID]]; ASIHTTPRequest *request = [[ASIHTTPRequest alloc]initWithURL:url]; [request s

ios开发之 APP上架要填写什么?有什么要注意?

好不容易把APP开发完成,那我们上架的时候要填写什么?注意些什么?(关于申请上架帐号神马的,请参阅个人之前的文章) 1.国内发布APP,名字肯定是中文.那么在项目info文件里边,把Bundle display name 填写一个中文名字,Localization native development regior 选择中国.如果刚才提到的两个都没有,自己手动添加即可. 2.项目General注意点 2-1:Bundle identifier 命名规范,且具有唯一性,因为在发布时候,描述证书要匹

iOS开发之APP推送设置WIFI

在iOS开发过程中,有时需要连接网络.当访问请求,检测到网络不可用时,需要提示用户手动进行设置网络并告知用户操作路径设置可用的网络. 只需一行代码即可实现: - (void)viewDidLoad { [super viewDidLoad]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.backgroundColor = [UIColor redColor]; button.frame = CGR

iOS开发之 app网络实时监测

1.在 #import "AppDelegate.h" { Reachability *hostReach; } 2.在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {}里 //监测网络情况 [[NSNotificationCenter defaultCenter] addObserver:self selecto

iOS开发之UIWebView 无缝切换到 WKWebView (IMYWebView)

WKWebView 是IOS8新增的 Web浏览视图 优点:   加载速度  比UIWebView提升差不多一倍的, 内存使用上面,反而还少了一半. 缺点:   WKWebView 不支持缓存 和   NSURLProtocol 拦截了 我建议如果对缓存不高的页面可以使用,用户体验会提高很多. 由于项目中以前都是用 UIWebView  而且还要兼容 IOS8  之前的机子.  所以  我创建了一个新类  IMYWebView   你只要全局替换 UIWebView 就能无缝升级到 WKWebV

李洪强IOS开发之iOS好项目收集

李洪强IOS开发之iOS好项目收集 在这里收集一些最近出现的比较实用好玩的框架或者项目,会不断更新 项目 简述 日期 SCTableViewCell 类似与QQ侧滑删除Cell的Demo 201501018 JHChainableAnimations 可读性好使用方便的动画库,语法类似与Masonry,使用链式编程 20150506 awesome-ios-chart iOS平台下的各种图表组件 20150513 DevArticles iOS Animation 主流炫酷动画框架(特效)收集整