暗黑模式(iOS多主題)完美設(shè)計實現(xiàn)

Introduce:

? ? ? ? ios暗黑模式,多主題多皮膚設(shè)計,用于解決在ios上實現(xiàn)可跟隨系統(tǒng)主題變更杈帐,也可不跟隨實現(xiàn)自定義主題模式設(shè)計。本sdk可以支持任意多個主題悟泵。開發(fā)習慣上極度契合ios開發(fā)習慣杈笔,對于復雜的主題設(shè)置類,均可使用對象的tkThemeChangeBlock進行回調(diào)設(shè)置變更糕非。優(yōu)勢:

1.代碼無侵入,輕量級SDK蒙具。上手簡單。完美解決多任務后臺主題即時變更朽肥,屏幕快照變更主體禁筏。

2.全局控制,效率極高衡招。用hashmap的形式管理block指針對象篱昔,輕量。

3.一切OC對象皆tkThemeChangeBlock主題回調(diào)始腾,根據(jù)主題的目前的索引變更主題州刽。

4.常用的UIKit的組件,賦予主題屬性浪箭,主題方法等穗椅。直接設(shè)置主題顏色、圖片數(shù)組即可山林。完全契合系統(tǒng)設(shè)置屬性房待,方法習慣邢羔。

5.設(shè)計原理完美,弱引用的形式回調(diào)桑孩,不會對項目產(chǎn)生內(nèi)存泄漏拜鹤,內(nèi)存占用不釋放問題。UIKit-View層即用即注冊流椒,跟隨對象釋放即銷毀敏簿。主題回調(diào)block即用即注冊,跟隨對象釋放即銷毀宣虾。

movie show

效果視頻如下:(ps:沒辦法惯裕,簡書只支持優(yōu)酷/騰訊視頻? 沒法去廣告 想看大視頻,點鏈接:https://v.youku.com/v_show/id_XNDcwNTcxODMwNA==.html


iOSDarkDemo.mp4

How To Get Started

1.導入? pod? 'TKThemeConfig'? ? ? ? //(ps: 本人會對sdk一直維護绣硝,放心使用 )

2.在使用到的地方 #import <TKThemeConfig/TKThemeConfig.h>

程序加載完畢初始化

How To Usage

1.便捷用法

? ? ? sdk封裝可常見的view控件蜻势。對于這些常見的控件,比如CALayer鹉胖,UIView握玛,UIImageView,UIButton甫菠, UILabel等15個組件進行了貼合開發(fā)者的屬性定制挠铲,在原屬性上加前綴TKTheme。能滿足80%以上的開發(fā)需求寂诱。 剩下的用萬能方法即可拂苹。有時間功夫的小伙伴可以加入一起完善便捷用法哦。 示例如下: // UIButton like //UIImageView like //CALayer like 痰洒。其它的可自行看頭文件

layer.tkThemebackgroundColors = @[UIColor.brownColor,UIColor.darkGrayColor];

[themeSeting setTkThemebackgroundColors:@[UIColor.redColor,UIColor.brownColor]];

[imageViewsetTkThemeimages:@[[UIImage imageNamed:@"001.jpg"],[UIImage imageNamed:@"002.jpg"]]];

2.萬能用法

? ? ? 一切皆object對象,一切對象具備tkThemeChangeBlock(NSObject+TKUpdate.h),變更主題會觸發(fā) 任意對象的tkThemeChangeBlock回調(diào)瓢棒,可以在這個回調(diào)做主題設(shè)置。 本回調(diào)為主線程带迟,進行UI主題變更音羞,但是不要做耗時操作囱桨,耗時操作放到異步非主線程即可仓犬。 示例如下: //view.tkThemeChangeBlock //navigationBar.navigationBar

self.view.tkThemeChangeBlock= ^(id? _Nullableitself,NSUIntegerthemeIndex) { //設(shè)置主題? ? }

self.navigationController.navigationBar.tkThemeChangeBlock = ^(id? _Nullable itself, NSUInteger themeIndex) { //設(shè)置主題? }

項目地址:https://github.com/Tkoul/TKThemeConfig

本文為原創(chuàng),啃了幾天泡面搞出來的舍肠。轉(zhuǎn)載注明出處搀继。喜歡的給個小星星。對不足的地方翠语,可以一起交流叽躯,提升。郵件:Tkoull@163.com

對簡書編輯器玩不轉(zhuǎn)肌括,有點丑点骑!設(shè)計思想后續(xù)補上。


PS:設(shè)計思路 2020-11-6

鑒于目前直逼6K的閱讀量,再懶我也得補上承諾的設(shè)計思路以及思想黑滴。(??? 我是真的懶)憨募。

API怎么設(shè)計?多主題拓展怎么設(shè)計袁辈?NO,NO,NO 對于我這種懶人來說菜谣,不講這些基礎(chǔ)東西了。咱們就講多主題設(shè)計的核心:

1.怎么跟隨設(shè)置晚缩,同步的去變更所有的展示層UI以及棧里面的視圖UI.

2.改變主題的即時性

3.對主app的性能影響

4.代碼執(zhí)行效率

5.對主APP代碼的侵入

以上以重要程度列出尾膊。主體變更,聯(lián)動所有的UI變更荞彼。

實現(xiàn)思路一:通知

有人說簡單冈敛,通知完事,實際上業(yè)界內(nèi)很多開源的就是這么設(shè)計實現(xiàn)的鸣皂。寫一個根類或者拓展類莺债,注冊通知不就OK啦,然而真的這么簡單嗎签夭?

通知實現(xiàn)原理:通知實際上是利用runtime動態(tài)的創(chuàng)建類齐邦,創(chuàng)建的規(guī)則是監(jiān)聽某個類的屬性時,會動態(tài)的創(chuàng)建這個類的子類第租,并且初始化也是對這個子類操作的措拇。比如現(xiàn)在有AClass,監(jiān)聽它的屬性慎宾,runtime會臨時動態(tài)的創(chuàng)建它的子類丐吓,如subAclass(實際是有一套規(guī)則,好像是noti—aclass趟据,別在意細節(jié)券犁,了解就行),同時把AClass的isa指針指向subAClass汹碱。那么后續(xù)粘衬,你對AClass所有的操作,方法調(diào)用咳促,實例化等其實都是在操作subAClass稚新。你打印實例對象的Class的時候,依然返回的是AClass跪腹,什么褂删?不是說isa都是指向subAClass了嗎?對的冲茸,沒錯屯阀,只不過為了很像缅帘,這種情況,系統(tǒng)api重寫了class方法难衰,強制的反回了AClass股毫。表面上看著對象是AClass,操作的卻是subAClass召衔,實際都是假象铃诬,為了達到看著這樣的效果,設(shè)計這個模式的大神是做了很多蒙蔽我們的工作苍凛。在subAClass里面會重寫監(jiān)聽的屬性的方法趣席,達到監(jiān)聽效果。

敲桌子1:回味下醇蝴,注冊一個通知的代價宣肚。。悠栓。

繼續(xù):每次注冊通知霉涨,都會在通知中心重新注冊一次,即使是同一對象惭适,監(jiān)聽同一個消息笙瑟,而不是去覆蓋原來的監(jiān)聽。這樣癞志,當通知中心轉(zhuǎn)發(fā)某一消息時往枷,如果同一對象多次注冊了這個通知的觀察者,則會收到多個通知凄杯。

敲桌子2:如果寫for循環(huán)推出來10000個UIViewContrl错洁,每個UIViewContrl上有很多子view,那么這時候會注冊多少通知戒突,對多少個類進行動態(tài)變更屯碴,創(chuàng)建呢?思考下膊存。

結(jié)論:通知量級很重导而,通知是在某些場景下做通知,而不是用在這個場景膝舅。也不建議在開發(fā)過程中注冊太多的通知嗡载,避免濫用。

百度做的性能對比:(借鑒下數(shù)據(jù)??)

條件:在上萬個視圖量級下真機iphone5s初始化CPU消耗初始化耗時仍稀!

系統(tǒng)暗黑? ? ? ? ? CPU消耗:50%? ? 初始化耗時:3312ms

HashTable? ? ? ? CPU消耗:50%? ? 初始化耗時:3341ms

Notification? ? CPU消耗:99%? ? 初始化耗時:5115ms

實現(xiàn)思路二:重寫object類,用全局hashmap記錄所有的棧里的對象埂息。存起來技潘,變更主體設(shè)置遥巴,再去這個hasmap里面讀所有的對象變更主題。有這么簡單嗎享幽?hashmap(我們的字典铲掐,數(shù)組均叫hashmap,不行就hasarry唄值桩,別在意細節(jié)??)

1.存時機? 初始化的時候存摆霉,還是加載到視圖存,是共性全存還是需要的視圖去存奔坟。

2.循環(huán)引用問題携栋。 NSMutableArry存的東西那么就會強制引用,那么不去手動釋放咳秉,移除婉支,會導致視圖不會被釋放,內(nèi)存泄漏澜建。有的小伙伴說向挖,我存weak指針,不好意思炕舵,存進來了何之,你敢釋放,我NSMutableArry就敢崩潰給你看咽筋。敲桌子帝美,留給愛探索的小好伙伴(那么我weak對象+NSPointerArray)呢?tips NSPointerArray和我們常用的數(shù)組一樣晤硕,但是他可以存空對象悼潭,為什么不用呢,甚至在開發(fā)中幾乎很難看到這個容器對象舞箍。

3.release時機和把控會很難

結(jié)論:依賴hashmap直接存儲對象以及通過UIView的didAddSubview舰褪,didMoveToSuperview重寫方法等很難實現(xiàn)。即時實現(xiàn)疏橄,也不是好的設(shè)計占拍,有點類似為解決問題而解決問題。同時對APP代碼入侵嚴重捎迫,內(nèi)存釋放同樣不好把控晃酒。

以上囊括了業(yè)內(nèi)的大多設(shè)計思路和實現(xiàn)。在我看來窄绒,均不是很理想贝次。

通知方式雖然方便,入侵少彰导,但是效率性能消耗極大蛔翅,被我首先pass掉敲茄。思路二,效率ok山析,性能略有欠缺堰燎,入侵性大,錯誤率高笋轨,穩(wěn)定性差秆剪,內(nèi)存容易泄露,會連環(huán)導致均不被釋放爵政。

怎么做到輕量仅讽,效率高,性能好茂卦,完全穩(wěn)定何什,我們就需要各管各的,無論怎么設(shè)計等龙,誰干誰的事情处渣,誰改變對別人沒影響。TKThemeConfig設(shè)計實現(xiàn)蛛砰,就具備這些特性罐栈。

即用即創(chuàng)建,一管理泥畅,一嗅探荠诬,一釋放。(專業(yè)點?? :哨兵)

1.即用即創(chuàng)建:對象需要具備變更主題的能力位仁,但是在創(chuàng)建的時候才會具備這個能力柑贞。并且只在初始化創(chuàng)建一次。

2.hashMap管理聂抢。管理的不是跟主題相關(guān)的對象(一般指繼承UIView的視圖钧嘶,但是有很多繼承obj的對象也具備主題顏色設(shè)置,這也是思路二無法萬能的痛點)琳疏,而是對象實例方法內(nèi)部變量block有决。結(jié)合反向block方式。在類初始化方法創(chuàng)建block空盼,同時全局hashMap(TKThemeConfig使用了單利)儲存該blcok书幕。 解決了全局hashmap跟該對象的引用關(guān)系,即它倆沒關(guān)系揽趾。存的是方法內(nèi)部初始化的blcok台汇,block內(nèi)部用的是對象的weak,不相互持有。這里涉及三者励七,1.全局hashmap? 2.對象實例方法內(nèi)部block(興趣的可以研究下globblock智袭,staticblock奔缠,mallocblock)掠抬,3.對象本身。三者只有hashmap和block強持有校哎,block和對象弱持有两波。hashmap和對象無關(guān)。對象在自己的生命周期內(nèi)闷哆,釋放時機均自己把控即依然遵循系統(tǒng)ARC管理腰奋,無侵入,完美抱怔!就是這個關(guān)鍵設(shè)計解決最核心的問題劣坊。

3.一嗅探,一釋放屈留。由于對象和blcok弱關(guān)系局冰,那么視圖對象釋放掉,對于視圖對象而言就結(jié)束了灌危,但是block還被hashmap強持有康二,怎么去釋放它呢?敲桌子勇蝙,嗅探-(我覺得是天才靈感沫勿,有木有??),在一段時間去反向回調(diào)blcok味混,去試探與他相關(guān)的weak類對象是否還在产雹,一旦嗅探到weak==nil,說明跟block引用的對象已經(jīng)釋放了翁锡,那么blcok就告訴hashmap說蔓挖,哥們,我管理的對象不在了盗誊,我也沒啥用了时甚,你把我弄死吧。那么hashmap就把blcok取出來置空哈踱,殺死荒适,釋放回收blcok所占的內(nèi)存。具體實現(xiàn)开镣,去down源碼閱讀即可刀诬,嗅探我這設(shè)置的15秒一次,因為我允許hashmap多持有blcok一會邪财,blcok本身就是一個很輕量的元素陕壹,存的一個指針而已质欲,占內(nèi)存可以忽略。同時遍歷很快糠馆,遍歷上萬次并移除都不到2毫秒嘶伟,在牛的app也不會有上萬個視圖層吧??。ok,這就是TKThemeConfig設(shè)計思想又碌。

敲黑板九昧,這是一種思想,可以應用于類似場景的任何地方毕匀,一種解決思路铸鹰,也是靈感所致。希望對讀者有所啟發(fā)皂岔。讀懂了會對你很有幫助蹋笼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市躁垛,隨后出現(xiàn)的幾起案子剖毯,更是在濱河造成了極大的恐慌,老刑警劉巖缤苫,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件速兔,死亡現(xiàn)場離奇詭異,居然都是意外死亡活玲,警方通過查閱死者的電腦和手機涣狗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舒憾,“玉大人镀钓,你說我怎么就攤上這事《朴兀” “怎么了丁溅?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長探遵。 經(jīng)常有香客問我窟赏,道長,這世上最難降的妖魔是什么箱季? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任涯穷,我火速辦了婚禮,結(jié)果婚禮上藏雏,老公的妹妹穿的比我還像新娘拷况。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布赚瘦。 她就那樣靜靜地躺著粟誓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪起意。 梳的紋絲不亂的頭發(fā)上鹰服,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音杜恰,去河邊找鬼获诈。 笑死仍源,一個胖子當著我的面吹牛心褐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笼踩,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼逗爹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嚎于?” 一聲冷哼從身側(cè)響起掘而,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎于购,沒想到半個月后袍睡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡肋僧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年斑胜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嫌吠。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡止潘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辫诅,到底是詐尸還是另有隱情凭戴,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布炕矮,位于F島的核電站么夫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏肤视。R本人自食惡果不足惜档痪,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望钢颂。 院中可真熱鬧钞它,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锯仪,卻和暖如春泵督,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庶喜。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工小腊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人久窟。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓秩冈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親斥扛。 傳聞我的和親對象是個殘疾皇子入问,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345