我們再介紹一個對iOS 5的重要補充功能:通過蘋果原生類庫自定義視圖外觀。在iOS 5以前,自定義原生控件的外觀并沒有原生支持,因此開發(fā)人員感覺很麻煩。開發(fā)人員經(jīng)常面臨的問題是修改一個控件所有實例的外觀。解決這個問題的正確方法是重寫一遍控件。但由于這么做非常費時,一些開發(fā)人員開始覆蓋或混寫一些方法,如drawRect:
。
從iOS 5開始,蘋果通過兩個協(xié)議(UIAppearance
和UIAppearanceContainer
)規(guī)范了對許多UIKit控件定制的支持。所有遵循UIAppearance
協(xié)議的UI控件通過定制都可以呈現(xiàn)各種外觀。不僅如此,UIAppearance
協(xié)議甚至允許開發(fā)者基于控件所屬的區(qū)域指定不同的外觀。也就是說,當(dāng)某個控件包含在特定視圖中時,可以指定它的外觀(如UIBarButtonItem
的tintColor
)。也可以獲取該控件類的外觀代理對象,用該代理定制外觀來實現(xiàn),下面來看一個例子。
要定制應(yīng)用中所有條形按鈕的顏色,可以在UIBarButtonItem
的外觀代理中設(shè)置tintColor
:
[[UIBarButtonItem appearance] setTintColor:[UIColor redColor]];
注意,iOS 4的時候setTintColor
方法就在UIBarButtonItem
中了,但它只會作用到某個特定的控件實例,而不是所有的此類控件。借助外觀代理對象,我們可以定制使用上述類創(chuàng)建的任意對象的外觀。
同樣,可以根據(jù)內(nèi)部包含的視圖采用如下方法來定制控件的外觀:
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTintColor:[UIColor redColor]];
第一個參數(shù)是以nil
結(jié)尾的所有容器類的列表,包括UINavigatorBar
、UIPopOverController
等遵循UIAppearanceContainer
協(xié)議的類。
從iOS 5開始,大多數(shù)UI元素都增加了對UIAppearance
協(xié)議的支持。此外,iOS 5中類似于UISwitch
的控件允許我們方便地將on開關(guān)的顏色變成設(shè)計師選定的顏色。現(xiàn)在,怎么確定哪些情況下能夠通過UIKit的外觀代理來定制所有元素(以及元素中的哪些屬性)呢?有兩種方式。老辦法是查閱文檔,另一個辦法是大多數(shù)開發(fā)人員使用的快捷方式:讀頭文件。打開對應(yīng)的UIKit元素的頭文件,其中所有帶有UI_APPEARANCE_SELECTOR
標(biāo)記的屬性都支持通過外觀代理來定制。舉個例子,UINavigationBar.h中的tintColor
屬性帶有UI_APPEARANCE_SELECTOR
標(biāo)記:
@property(nonatomic,retain) UIColor *tintColor UI_APPEARANCE_SELECTOR;
意味著可以調(diào)用
[[UINavigationBar appearance] setTintColor:newColor];
盡管一開始蘋果反對(在Mac和iOS平臺上)使用UI定制,但情況慢慢發(fā)生了變化。蘋果自己的原生應(yīng)用(比如新的Reminder應(yīng)用)也有了深度定制的、模仿現(xiàn)實的用戶界面。有了UIAppearance
協(xié)議,實現(xiàn)同樣效果所用的代碼要少得多。