A pure Swift implemented library(extension) to change/switch app theme/skin 主题切换/换肤
A lightweight and pure Swift implemented library for switch app theme/skin. Chameleon aim at provide easy way to enable to app switch theme
If your have any question, you can email me([email protected]) or leave message.
You can define you theme with any data. Let's assume you theme data is ThemeStyle (Day, Night). ThemeStyle is enum type, however you can define your theme with any type.
1, Enable view to switch theme ability:
let label = UILabel()
label.ch.refreshBlock = { (now:Any, pre:Any?) -> Void in
// your code change theme/skin
if let now = ChameleonHelper<ThemeStyle>.parse(now) { // get your ThemeStyle from now
label.text = "\(now)"
...
}
}
Or your can override method of view: switchTheme(now:pre:)
override func switchTheme(now: Any, pre: Any?) {
// your code change theme/skin
if let now = ChameleonHelper<ThemeStyle>.parse(now) {
...
}
}
2 Set your Theme
ThemeServiceConfig.shared.initTheme(data: ThemeStyle.Day)
3 Switch Theme
UIApplication.ch.refresh(with: ThemeStyle.Night)
viewInstance.ch.refresh(with: ThemeStyle.Night)
viewControllerInstance.ch.refresh(with: ThemeStyle.Night)
Some useful function define in ChameleonHelper.
1, Auto callback config To save your time, ThemeServiceConfig may be your favor. Several properties are pre defined for you. When given property is true, ch.refreshBlock or switchTheme(now:pre:) of ChameleonUIProtocol user it's parent data
// config your theme switch
ThemeServiceConfig.shared.autoSwitch = [.viewDidMoveToWindow, .viewControllerViewWillAppear]
Note: Auto call is convenient and save your time, but you should follow some rules, or else you may be in trouble.
2, Call orders:
Note:
4, You may find your switch theme method not call when you view controller is beyond application rootViewController tree. In this case, you normal is call ch.register()
viewControllerInstance.ch.register()
In most cases, your do not need call this method, how ever your are free to call this method at any time
default support is Swift 4. If you use it in prevous version of Swift. 2.x for Swift3.
version 2.2 is break change. server changes should apply:
CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:
$ gem install cocoapods
To integrate ChameleonSwift into your Xcode project using CocoaPods, specify it in your Podfile
:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'ChameleonSwift'
Then, run the following command:
$ pod install
You should open the {Project}.xcworkspace
instead of the {Project}.xcodeproj
after you installed anything from CocoaPods.
ChameleonSwift 提供了一种机制,你可以很方便的使得你的 App 具有多种皮肤和主题.。ChameleonSwift 是一个纯 Swift 实现的扩展。 由于主题/皮肤切换的复杂性,考虑到易于使用和可扩展行,本库并没有采用其他大多数库采用的方式(为不同的 view 添加不同的属性以达到主题切换),而是采用的是扩展 UIView, UIViewController的方式,你可以高度的定制你想要的皮肤。
和其他主题或者皮肤库优点:
假设你使用默认的 ThemeStyle(枚举类型,由Day, Night), 下面代码中使用 ThemeStyle 作为你使用的主题类型; 当然在实际使用中, 可以完成你自己定义的主题类型,可以是枚举,数字,类,可以是任意类型
有两种方式:你可以通过闭包,也可以通过 override 父类的方法来实现 闭包实现
let label = UILabel()
label.ch.refreshBlock = { (now:Any, pre:Any?) -> Void in
// 你修改主题的代码
if let now = ChameleonHelper<你定义的主题类型>.parse(now) { // 获取 真正的主题
label.text = "\(now)"
...
}
}
override func switchTheme(now: Any, pre: Any?) {
// your code change theme/skin
if let now = ChameleonHelper<ThemeStyle>.parse(now) {
...
}
}
参数说明:
* now: 你切换主题是传递进来的参数,比如是白天,还是黑夜等待。你可以用 ChameleonHelper<你定义的主题类型>.parse(now),获取当前的主题
* pre: 上次你主题切换使用的参数
好了,通过上面的步骤你已经使得你的view可以支持多种主题了
### 第二步: 设置的主题数据
* 设置整个app
``` swift
ThemeServiceConfig.shared.initTheme(data: ThemeStyle.Day)
viewInstance.ch.refresh(with: ThemeStyle.Night)
viewControllerInstance.ch.refresh(with: ThemeStyle.Night)
你只需要调用一个方法就可以实现
UIApplication.ch.refresh(with: ThemeStyle.Night)
当然,你可以选择行的修改你想要改变view / view controller 的主题 view 切换调用:
viewInstance.ch.refresh(with: ThemeStyle.Night)
view controller 调用:
viewControllerInstance.ch.refresh(with: ThemeStyle.Night)
默认支持的为Swift 4版本,如果需要在 Swift 2 版本使用, 请使用 2.x的版本
ChameleonHelper定义了一些有用的函数
在简单使用中,介绍了如何让你的 App 支持主题切换和如何进行切换。但是,你会发现还是很不方面,你需要不怨其烦的手动调用,主题修改的方法。为你将你从这种无止境的烦恼中解放出来。为你提供了主题切换自动调用配置 ThemeServiceConfig。提供的配置,可以满足你的绝大数需求。
是不是,很方便,简单?
不过任何好用,其实都是由代价的,自动调用使得主题切换调用更隐晦,响应的也不容易调试。为了你更好的使用自动调用,几点注意事项
1,闭包 ch.refreshBlock 和 ChameleonUIProtocol 同时存在,会出现什么问题? 闭包和 ChameleonUIProtocol 都会被调用,只不过闭包会在 ChameleonUIProtocol 调用的后面调用
2,view controller 主题切换闭包,函数没有调用. 如果一个修改主题的方法写在一个view controller中,而在使用的时候 只是将 controller的view添加到某个view上,而view controller本身没有加到任何 view controller下的时候, 可能出现 该 view contoller的方法,并没有自动调用或者在主题切换的时候也没有自动调用?怎么处理 其实出现这种情况是正常的,这个涉及到本库切换的设计原理(后面提到)。你需要人为的调用主题切换方法,并 viewControllerInstance.ch.register()进行注册。就可以实现 viewControllerInstance.ch.register() 这个方法在绝大多数的时候,你可以任何地方使用,不过建议在本情况出现的时候调用(可能导致调用顺序异常)
3,主题切换函数或闭包调用顺序问题:
版本 2.2 和以前的api是不兼容的, 重要的修改如下:
采用的是扩展 view,view controller的方式来实现的。 主题切换的时候,是通过遍历 app 的view 和 view controller 树来实现切换的。
本库已经在某新闻 App 中使用,经得住考验~