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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • swift在IOS应用图标上添加提醒个数的方法

    在应用图标右上角添加消息数提醒,可以很方便的告知用户该应用中有无新消息需要处理.下面用xcode 7.3.1来简要说明一下如何用swift语言进行此功能的实现. 1.修改 AppDelegate.swift // // AppDelegate.swift // RainbowDemo // // Created by Jackwang on 16/8/17. // Copyright © 2016年 Jackwang . All rights reserved. // import UIKit

  • ios swift3.0实现二维码扫描、生成、识别示例代码

    基于swift3.0 1.扫描二维码 设置扫描会话,图层和输入输出 //设置捕捉设备 let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) do { //设置设备输入输出 let input = try AVCaptureDeviceInput(device: device) let output = AVCaptureMetadataOutput() output.setMetadataObjec

  • IOS Swift3 四种单例模式详解及实例

    Swift3 单例模式 常见的有这么几种方法 第一种简单到爆的 final class Single: NSObject { static let shared = Single() private override init() {} } final关键字的作用是这个类或方法不希望被继承和重写 第二种 public extension DispatchQueue { private static var onceToken = [String]() public class func once

  • IOS开发OC代码中创建Swift编写的视图控制器

    IOS开发OC代码中创建Swift编写的视图控制器 背景 近日在和一群朋友做项目,我和另一位同学负责iOS客户端,我是一直使用OC的,而他只会Swift,因此在我们分工协作之后,就需要把代码合在一起,这就牵扯到如何在TabbarController中添加一个swift创建的子控制器的问题. 解决 首先在一个OC项目中新建一个Swift类,继承自UITableViewController,并且修改其view背景色,方便后续测试. import UIKit class ESSwiftTableVie

  • 使用Swift实现iOScollectionView广告无限滚动效果(DEMO)

    今天公司里的实习生跑过来问我一般App上广告的无限滚动是怎么实现的,刚好很久没写博客了,就决定写下了,尽量帮助那些处于刚学iOS的程序猿. 做一个小demo,大概实现效果如下图所示: 基本实现思路: 1. 在你需要放置无限滚动展示数据的地方把他的数据,在原本的基础上把你要展示的数据扩大三倍.(当然扩大两倍也是可以的,三倍的话,比较好演示) // MARK: - 设置数据源 func collectionView(_ collectionView: UICollectionView, number

  • iOS开发中Swift3 监听UITextView文字改变的方法(三种方法)

    在项目中使用文本输入框出UITextField之外还会经常使用 UITextView ,难免会有需求监听UITextView文本框内文本数量.下面介绍在swift3中两种常用方式 方式一: 全局通知 1.注册通知 在合适位置注册监听UITextView文本变化的全局通知 //UITextView 监听开始输入的两种方法 //方法一:通知 NotificationCenter.default.addObserver(self, selector: #selector(ComposeVC.textV

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

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

  • iOS开发之APP相关

    AppDelegate对象方法 复制代码 代码如下: # 程序第一次启动后才会执行 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; # 程序将要失去焦点时执行 - (void)applicationWillResignActive:(UIApplication *)application; # 程序得到焦点时调用 - (voi

  • IOS开发之UIScrollView实现图片轮播器的无限滚动

    IOS开发之UIScrollView实现图片轮播器的无限滚动 简介 在现在的一些App中常常见到图片轮播器,一般用于展示广告.新闻等数据,在iOS内并没有现成的控件直接实现这种功能,但是通过UIScrollView的允许分页设置,可以实现滚动轮播的功能. 轮播原理 UIScrollView对象有pagingEnable成员,如果设置为YES,那么每一个scrollView尺寸这么大的区域就会被当作一页,在滚动时会根据滚动的比例自动计算应该切换到哪一页. 无限滚动原理 要实现无限滚动,需要额外的两

  • IOS 开发之xcode对比两个分支中同一个文件

    IOS 开发之xcode对比两个分支中同一个文件 对于同一个项目的两个分支,因为两个分支可能各自都做了一些修改,所以通过Source Control中的History...功能是无法查看的,如下图: 这个时候,我们需要用到xcode的另外一个功能,如图: 操作步骤: 1.点击图中标注为1红框中的按钮,中间的界面会出现并排的两个窗口3和4(窗口3为当前分支文件内容). 2.从另外一个分支的xcode窗口中选中同名的文件,然后使用"command+`"切换到当前的xcode窗口. 3.拖动

  • IOS 开发之PickerView文字和随机数的使用

    IOS 开发之PickerView文字和随机数的使用 PickerView用于展示供选择的内容(例如日期选取.点菜等). 有三种情况: 1.每一列都是独立的选取 2.右边的列受到左边列的影响 3.包含图片 PickerView和TableView类似,通过数据源来显示数据,与TableView同样地,让控制器称为其数据源. 但是PickerView的数据源仅仅提供行数和列数,在代理方法内才能设置内容. 通过两个数据源方法设置行和列数,通过一个代理方法来设定内容,注意component表示第几列:

  • iOS开发之UIKeyboardTypeNumberPad数字键盘自定义按键

    最近做一个搜索用户的功能,这里使用了UISearchBar.由于搜索的方式只有手机号码,所以这里的键盘要限制为数字输入,可以这么做: self.searchBar.keyboardType = UIKeyboardTypeNumberPad;如果使用的不是搜索框而是textField输入框,可以设置textField的键盘属性来展示 self.textField.keyboardType = UIKeyboardTypeNumberPad;监听事件如下所示即可. 但是这里有个问题,就是数字键盘上

  • iOS开发之UIMenuController使用示例详解

    目录 简介 接口介绍 使用探索 如何创建并显示 UIMenuController 实现 Item 点击事件 菜单 Item 太多??? UIResponderStandardEditActions 协议 添加自定义菜单 箭头的方向 实际使用 总结 简介 UIMenuController 是一个菜单编辑界面,在很多地方都能用到,通常用于剪切.复制.粘贴.选择.全选和删除命令等,也可以自定义想要的操作,它长这样: 接口介绍 open class UIMenuController : NSObject

  • IOS开发之@property的详细介绍

    IOS开发之@property的详细介绍 在类中定义属性时,总会使用到@property进行定义,下面就来说说@property的使用. 在使用过程中,如果需求公开且在其他类中使用时,通常会定义在.h头文件中:而如果只是该类自已需要使用,这时则会定义 在.m实现文件中. 使用格式 @property (参数1, 参数2, 参数3, ...) 参数类型 参数名称 参数包括三个种类,七个属性,如下图所示. 在使用过程中,有几点需要注意: (1)原子性定义中,如果没有涉及到多线程环境时,通常不会使用默

  • IOS 开发之swift中UIView的扩展使用的实例

    IOS 开发之swift中UIView的扩展使用的实例 扩展类代码: import UIKit extension UIView { // MARK : 坐标尺寸 var origin:CGPoint { get { return self.frame.origin } set(newValue) { var rect = self.frame rect.origin = newValue self.frame = rect } } var size:CGSize { get { return

  • iOS开发之UITableView与UISearchController实现搜索及上拉加载,下拉刷新实例代码

    废话不多说了,直接给大家贴代码了. 具体代码如下所示: #import "ViewController.h" #import "TuanGouModel.h" #import "TuanGouTableViewCell.h" #define kDeviceWidth [UIScreen mainScreen].bounds.size.width #define kDeviceHeight [UIScreen mainScreen].bounds.

随机推荐