1. 程式人生 > 實用技巧 >Swift主題色頂級解決方案

Swift主題色頂級解決方案

一、常規主題色使用點

應用在釋出前都會對其主題色進行設定,以統一應用的風格(可能有多套主題)。在主題色設定上有幾個方面,如下:

1.TabBar部分,設定圖片高亮、文字高度顏色

2.NavigationBar部分,設定導航欄顏色及字型顏色

3.應用標籤等,設定字型的顏色

4.應用圖片主題色

主題色的設定點,大體從上面四個方面著手,圖片的主題色我們可通過圖片更換的方式進行處理。而通過程式碼來處理的`1-3`條,有著不同的處理方法。大家常規處理方法如下:

步驟一:變化分離

1.利用Swift擴充套件語法擴充套件UIColor,將應用主題色在擴充套件中統一處理(適合單一主題色)

2.將主題色的配置寫入檔案中,由相應邏輯進行解析。此方法將主題色邏輯封裝成主題色管理類(適合多套主題)

步驟二:離散使用上步封裝的類

1.在任何使用主題色的地方,使用擴充套件中的UIColor方法來設定,一般包括背景色,文字顏色等

這裡給出UIColor的擴充套件

extensionUIColor{

//主題色
classfuncapplicationMainColor()->UIColor{
returnUIColor(red:238/255,green:64/255,blue:86/255,alpha:1)
}

//第二主題色
classfuncapplicationSecondColor()->UIColor{
returnUIColor.lightGrayColor()
}

//警告顏色
classfuncapplicationWarningColor()->UIColor{
returnUIColor(red:0.1,green:1,blue:0,alpha:1)
}

//連結顏色
classfuncapplicationLinkColor()->UIColor{
returnUIColor(red:59/255,green:89/255,blue:152/255,alpha:1)
}

}

二、TabBar主題色設定

很多應用中,預設情況下都使用了TabBar控制元件,但是TabBar主題色等設定根據使用情況的不同,設定起來也不一樣。程式碼建立比較靈活,更改主題色比較容易。而使用了Xib/Storyboard也是有辦法做統一處理的,如下,迭代更改TabBar預設字型顏色

funcconfigTabBar(){
letitems=self.tabBar.items
foriteminitemsas[UITabBarItem]{
letdic=NSDictionary(object:UIColor.applicationMainColor(),
forKey:	NSForegroundColorAttributeName)
item.setTitleTextAttributes(dic,
forState:UIControlState.Selected)
}
}

設定TabBar圖片及文字預設選中顏色

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.

在一些情況,正常狀態為白色圖片時,真機測試時,白色圖片會出現偏色(顯示結果為灰色),這是因為系統預設著色導致的,在建立UITabBarItem時,可通過使用UIImageRenderingModeAlwaysOriginal避免。示例程式碼如下:

letimageNormal=UIImage(contentsOfFile:"imageNormal")?.
imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
letimageSelected=UIImage(contentsOfFile:"imageSelected")
lettabBarItem=UITabBarItem(title:"title",
image:imageNormal,
selectedImage:imageSelected)

三、一勞永逸,利用Hook原理通設NavigationBar顏色

IOS應用中,NavigationBar十分常用,它的使用主要包括以下兩個場景

1.程式碼直接構建

2.Xib/Storyboard構建

如果是純程式碼構建的時候,比較簡單,直接使用UIColor的擴充套件來設定顏色。實際專案中,有些介面是通過Xib/Storyboard來建立的,有些是程式碼寫的,但這也難不到大家,使用繼承。建立一個繼承自UINavigationController的子類,通過這個子類來統一設定主題色。然後告訴專案中的所有人,強制使用UINavigationController子類,包括Xib/Storyboard等。問題是舊專案怎麼辦,這種強制要求可以工作,有沒有一個更好的辦法,讓所有人正常使用UINavigationController,而在神不知鬼不覺的情況下,通設所有NavigationBar呢?

先上程式碼,再解釋

1.建立一個UIViewController的擴充套件

extensionUIViewController{
funcviewDidLoadForChangeTitleColor(){
self.viewDidLoadForChangeTitleColor()
ifself.isKindOfClass(UINavigationController.classForCoder()){
self.changeNavigationBarTextColor(selfasUINavigationController)
}
}

funcchangeNavigationBarTextColor(navController:UINavigationController){
letnav=navControllerasUINavigationController
letdic=NSDictionary(object:UIColor.applicationMainColor(),
forKey:NSForegroundColorAttributeName)
nav.navigationBar.titleTextAttributes=dic
nav.navigationBar.barTintColor=UIColor.applicationSecondColor()
nav.navigationBar.tintColor=UIColor.applicationMainColor()

}

}

2.編寫用於Hook的工具類

funcswizzlingMethod(clzz:AnyClass,#oldSelector:Selector,#newSelector:Selector){
letoldMethod=class_getInstanceMethod(clzz,oldSelector)
letnewMethod=class_getInstanceMethod(clzz,newSelector)
method_exchangeImplementations(oldMethod,newMethod)
}

3.在AppDelegate中呼叫

funcapplication(application:UIApplication,didFinishLaunchingWithOptionslaunchOptions:NSDictionary?)->Bool{
swizzlingMethod(UIViewController.self,
oldSelector:"viewDidLoad",
newSelector:"viewDidLoadForChangeTitleColor")
	//doothers
returntrue
}

4.原理說明

在程式入口處,通過執行時機制,動態的替換UIViewController的週期方法viewDidLoad為我們指定的方法viewDidLoadForChangeTitleColor。在viewDidLoadChangeTitleColor中,需要做兩件事:

* 呼叫原來的viewDidLoad方法

* 執行修改主題色相關程式碼

1.如何呼叫原來的viewDidLoad方法

在AppDelegate中,通過呼叫方法`swizzlingMethod`我們將viewDidLoad與viewDidLoadForChangeTitleColor方法體進行了替換,原理如下圖:

從上面的圖可以看出,當在viewDidLoadForChangeTitleColor中執行:

self.viewDidLoadForChangeTitleColor()

是不會造成迴圈呼叫,反而是呼叫了我們期望執行的viewDidLoad方法體。

三、Xib/Storyboard的處理

一些在Xib/Storyboard中設定的主題色,比如文字顏色,按鈕的高亮顏色等,該如何處理呢,以UILabel為例,建立擴充套件

extensionUILabel{
varcolorString:String{
set(newValue){
switchnewValue{
case"main":
self.textColor=UIColor.applicationMainColor()
case"second":
self.textColor=UIColor.applicationSecondColor()
case"warning":
self.textColor=UIColor.applicationWarningColor()
default:
self.textColor=UIColor.applicationSecondColor()
}
}
get{
returnself.colorString
}
}
}

在Xib/Storyboard的查檢器中進行編輯,如下圖:

extensionUILabel{
varcolorString:String{
set(newValue){
switchnewValue{
case"main":
self.textColor=UIColor.applicationMainColor()
case"second":
self.textColor=UIColor.applicationSecondColor()
case"warning":
self.textColor=UIColor.applicationWarningColor()
default:
self.textColor=UIColor.applicationSecondColor()
}
}
get{
returnself.colorString
}
}
}

4.總結

1.只有一套主題時,上面的方法可以直接複製使用,在更換主題時,只需要更換相應圖片及修改UIColor的擴充套件類

2.在有多套主題,使用者可以自由切換主題時,可以按文章中的Hook機制,對viewWillAppear進行劫持,也可以輕鬆實現主題的改變

來源:揚中網站建設