1、常規主題色使用點
應用在發佈前都會對其主題色進行設置,以統一應用的風格(可能有多套主題)。在主題色設置上有幾個方面,以下:app
1.TabBar部分,設置圖片高亮、文本高度顏色 2.NavigationBar部分,設置導航欄顏色及字體顏色 3.應用標籤等,設置字體的顏色 4.應用圖片主題色
主題色的設置點,大致從上面四個方面着手,圖片的主題色咱們可經過圖片更換的方式進行處理。而經過代碼來處理的1-3
條,有着不一樣的處理方法。你們常規處理方法以下:
ide
步驟一:變化分離
1.利用Swift擴展語法擴展UIColor,將應用主題色在擴展中統一處理(適合單一主題色)
2.將主題色的配置寫入文件中,由相應邏輯進行解析。此方法將主題色邏輯封裝成主題色管理類(適合多套主題)工具
步驟二:離散使用上步封裝的類post
1.在任何使用主題色的地方,使用擴展中的UIColor方法來設置,通常包括背景色,文字顏色等
這裏給出UIColor的擴展測試
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
extension UIColor {
//主題色
class func applicationMainColor() -> UIColor {
return UIColor(red: 238/255, green: 64/255, blue: 86/255, alpha:1)
}
//第二主題色
class func applicationSecondColor() -> UIColor {
return UIColor.lightGrayColor()
}
//警告顏色
class func applicationWarningColor() -> UIColor {
return UIColor(red: 0.1, green: 1, blue: 0, alpha: 1)
}
//連接顏色
class func applicationLinkColor() -> UIColor {
return UIColor(red: 59/255, green: 89/255, blue: 152/255, alpha:1)
}
}
|
2、TabBar主題色設置
不少應用中,默認狀況下都使用了TabBar控件,可是TabBar主題色等設置根據使用狀況的不一樣,設置起來也不同。代碼建立比較靈活,更改主題色比較容易。而使用了Xib/Storyboard也是有辦法作統一處理的,以下,迭代更改TabBar默認字體顏色字體
1
2
3
4
5
6
7
8
9
10
|
func configTabBar() {
let items = self.tabBar.items
for item in items as [UITabBarItem] {
let dic = NSDictionary(object: UIColor.applicationMainColor(),
forKey:
NSForegroundColorAttributeName)
item.setTitleTextAttributes(dic,
forState:
UIControlState.Selected)
}
}
|
設置TabBar圖片及文字默認選中顏色this
1
|
self.tabBar.selectedImageTintColor = UIColor.applicationMainColor()
|
Tips注意事項
Changing this property’s value provides visual feedback in the user interface, including the running of any associated animations. The selected item displays the tab bar item’s selectedImage image, using the tab bar’s selectedImageTintColor value. To prevent system coloring of an item, provide images using the UIImageRenderingModeAlwaysOriginal rendering mode.spa
在一些狀況,正常狀態爲白色圖片時,真機測試時,白色圖片會出現偏色(顯示結果爲灰色),這是由於系統默認着色致使的,在建立UITabBarItem時,可經過使用UIImageRenderingModeAlwaysOriginal避免。示例代碼以下:3d
1
2
3
4
5
6
|
let imageNormal = UIImage(contentsOfFile: "imageNormal")?.
imageWithRenderingMode(
UIImageRenderingMode.AlwaysOriginal)
let imageSelected = UIImage(contentsOfFile: "imageSelected")
let tabBarItem = UITabBarItem(title: "title",
image: imageNormal,
selectedImage: imageSelected)
|
3、一勞永逸,利用Hook原理通設NavigationBar顏色
IOS應用中,NavigationBar十分經常使用,它的使用主要包括如下兩個場景
1.代碼直接構建
2.Xib/Storyboard構建
若是是純代碼構建的時候,比較簡單,直接使用UIColor的擴展來設置顏色。實際項目中,有些界面是經過Xib/Storyboard來建立的,有些是代碼寫的,但這也難不到你們,使用繼承。建立一個繼承自UINavigationController的子類,經過這個子類來統一設置主題色。而後告訴項目中的全部人,強制使用UINavigationController子類,包括Xib/Storyboard等。問題是舊項目怎麼辦,這種強制要求能夠工做,有沒有一個更好的辦法,讓全部人正常使用UINavigationController,而在神不知鬼不覺的狀況下,通設全部NavigationBar呢?
先上代碼,再解釋
1.建立一個UIViewController的擴展
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
extension UIViewController {
func viewDidLoadForChangeTitleColor() {
self.viewDidLoadForChangeTitleColor()
if self.isKindOfClass(UINavigationController.classForCoder()) {
self.changeNavigationBarTextColor(self as UINavigationController)
}
}
func changeNavigationBarTextColor(navController: UINavigationController) {
let nav = navController as UINavigationController
let dic = NSDictionary(object: UIColor.applicationMainColor(),
forKey:
NSForegroundColorAttributeName)
nav.navigationBar.titleTextAttributes = dic
nav.navigationBar.barTintColor =
UIColor.applicationSecondColor()
nav.navigationBar.tintColor =
UIColor.applicationMainColor()
}
}
|
2.編寫用於Hook的工具類
1
2
3
4
5
|
func swizzlingMethod(clzz: AnyClass, #oldSelector: Selector, #newSelector: Selector) {
let oldMethod = class_getInstanceMethod(clzz, oldSelector)
let newMethod = class_getInstanceMethod(clzz, newSelector)
method_exchangeImplementations(oldMethod, newMethod)
}
|
3.在AppDelegate中調用
1
2
3
4
5
6
7
|
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
swizzlingMethod(
UIViewController.self,
oldSelector:
"viewDidLoad",
newSelector:
"viewDidLoadForChangeTitleColor")
//do others
return true
}
|
4.原理說明
在程序入口處,經過運行時機制,動態的替換UIViewController的週期方法viewDidLoad爲咱們指定的方法viewDidLoadForChangeTitleColor。在viewDidLoadChangeTitleColor中,須要作兩件事:
- 調用原來的viewDidLoad方法
- 執行修改主題色相關代碼
1.如何調用原來的viewDidLoad方法
在AppDelegate中,經過調用方法swizzlingMethod
咱們將viewDidLoad與viewDidLoadForChangeTitleColor方法體進行了替換,原理以下圖:
從上面的圖能夠看出,當在viewDidLoadForChangeTitleColor中執行:
1
|
self.viewDidLoadForChangeTitleColor()
|
是不會形成循環調用,反而是調用了咱們指望執行的viewDidLoad方法體。
3、Xib/Storyboard的處理
一些在Xib/Storyboard中設置的主題色,好比文本顏色,按鈕的高亮顏色等,該如何處理呢,以UILabel爲例,創建擴展
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
extension UILabel {
var colorString: String {
set(newValue) {
switch newValue {
case "main":
self.textColor = UIColor.applicationMainColor()
case "second":
self.textColor = UIColor.applicationSecondColor()
case "warning":
self.textColor = UIColor.applicationWarningColor()
default:
self.textColor = UIColor.applicationSecondColor()
}
}
get {
return self.colorString
}
}
}
|
4.總結
1.只有一套主題時,上面的方法能夠直接複製使用,在更換主題時,只須要更換相應圖片及修改UIColor的擴展類
2.在有多套主題,用戶能夠自由切換主題時,能夠按文章中的Hook機制,對viewWillAppear進行劫持,也能夠輕鬆實現主題的改變