原創:liushaohua 百度APP技術團隊
bash
在2019WWDC的開場演講中,蘋果公佈了即將推出的iOS13 DarkMode的新特性。此新特性不只能夠在夜晚保護視力,並且對於使用OLED的最新一代設備而言,也能夠幫助用戶節省電量消耗。不過此特性只支持iOS13以上的系統,爲了給全系統全部用戶最好的體驗,研發出了一套皮膚主題框架,不只能夠全系統支持DarkMode,還能夠擴展多套皮膚主題;架構
// UIColor
view.backgroundColor = BDPAppearanceColor(@"C1");
// UIImage
imageV.image = BDPAppearanceImage(@"icon");
複製代碼
先來看一下BDPAppearance設計方案的架構圖: 框架
而內置的UIImage圖片是存放在Assets中的,經過BDPAppearanceImage用圖片名去加載當前主題下的UIImage對象便可;ide
能夠看到圖中,給UIColor分類添加了ColorName屬性: 經過BDPAppearanceColor方式獲取UIColor實例對象時,經過分類會記錄當前Color對象所使用的色號名;工具
同理,經過BDPAppearanceImage獲取UIImage時,經過分類會記錄當前Image對象所使用的圖片名;組件化
每個控件初始化添加到父視圖的時候,在- (void)didMoveToSuperview的時機將其添加到NSHashTable中, 點擊切換主題時,經過NSHashTable拿到當前視圖樹上全部的視圖控件,取出控件屬性中的UIColor和UIImage, 判斷其colorName和imageName是否有值,有值即表明當前控件須要適配主題,則用此colorName或者imageName去加載當前主題的新色值和新圖片,從新賦值給當前控件即完成了主題切換。佈局
設計此皮膚主題框架的原則:性能
業務方在現有業務的基礎上以最低成本的方式進行適配:即只需更換獲取顏色和圖片的方式學習
那麼在基於上述原則的前提下,咱們應該如何在切換主題時,讓全部的控件從新刷新主題呢?測試
在項目初期時,採用通知的方案:在didMoveToSuperview方法中給當前控件添加一個通知,當收到切換主題的通知時,則刷新當前控件的相關色值及圖片;
可是在作性能測試時,發現採用通知方式初始化,不只會有必定CPU消耗,同時也會增長初始化的耗時,視圖層級越多,性能損耗越明顯,因此放棄了此方案; 咱們的目的其實就是可讓當前全部的視圖能夠觸發刷新邏輯,最終採用了NSHashTable弱持有控件的方案;
兩種方式性能測試數據:
如下數據均是測試20次以上取的平均值;
壓力測試環境:視圖層級1w個View:
如下是目前業界GitHub排名靠前的開源庫對比:
UIColor *dynamicColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
return [UIColor blackColor];
} else {
return [UIColor whiteColor];
}
}];
view.backgroundColor = dynamicColor;
複製代碼
對比能夠看出:BDPAppearance使用方式是在保留RD開發習慣上的基礎上最接近系統方式的,改動代碼量是最小的;
百度App涉及到主題相關模塊技術形態有:NA、H五、RN、HN等,而在多種技術形態下主題模式又是如何通訊呢?能夠參考下邊這張圖:
整個百度App涉及近百個業務,組件近三百個,色號表的管理也顯得尤其重要;
每一個組件內部所使用到的色號僅僅是有限個, 若是全部組件用到的色值都統一放入一個色值表中管理,顯然是不合理的,不利於解耦也更不利於組件化輸出;那麼最優的色值管理方式是什麼呢?
早期的開發中,UE出圖都是用的Sketch導出HTML格式標註圖,而根據百度App iOS相關 CRD、FE 對實現技術的選型及配合要求,UE 須要提供並維護一套 NA+H5 色表,標註界面時標顏色的編號而非色值。爲了達到此種效果,咱們同期研發出了Sketch插件,能夠在標註界面直接顯示出色號,解決了UE標註色號的痛點,大大提升了效率; 以下圖:
一鍵轉換深色、夜間等主題
熟悉的標註導出方式,全部標註均在一處
在整套皮膚主題機制下業務方僅僅花了不到兩週的時間即完成了整個手百的主題適配,也從側面證明此框架的優勢:輕量級,使用成本低;
資源配置同時也支持雲端下發,可動態新增多種主題;
效果請查看:mp.weixin.qq.com/s/QOPCCIC-P…
本文主要從皮膚主題框架實現、色值表的管理以及配套工具鏈等方面詳細的介紹了百度App iOS暗黑模式的適配,歡迎業內的朋友一塊兒交流學習;