動(dòng)態(tài)修改UINavigationBar的背景色

07 APRIL 2015onios,objc,uinavigationbar

這是我們最終想要得到的效果:

思路

在UISrollView的delegate方法- (void)scrollViewDidScroll:(UIScrollView *)scrollView中根據(jù)當(dāng)前的contentOffset更新navigationBar的backgroundColor即可亲澡,so easy~

開動(dòng)

那么我們來看看apple為我們提供了哪些API來設(shè)置navigationBar的顏色贫堰。

首先想到的是最常用的[UINavigationBar appearance],我們一般會(huì)在AppDelegate中使用它對(duì)navigationBar進(jìn)行統(tǒng)一的設(shè)置。但是如果試一下照藻,會(huì)發(fā)現(xiàn)在scrollViewDidScrollView中調(diào)用它并不能動(dòng)態(tài)地改變navigationBar的顏色饺鹃,原因可以看一下Apple的doc:

Use the UIAppearance protocol to get the appearance proxy for a class. You can customize the appearance of instances of a class by sending appearance modification messages to the class’s appearance proxy.

但是:

iOS applies appearance changes when a view enters a window, it doesn’t change the appearance of a view that’s already in a window. To change the appearance of a view that’s currently in a window, remove the view from the view hierarchy and then put it back.

所以換一條路,直接修改UINavigationBar的backgroudColor:

- (void)scrollViewDidScroll:(UIScrollView*)scrollView{UIColor*color = [UIColorblueColor];CGFloatoffsetY = scrollView.contentOffset.y;if(offsetY >0) {CGFloatalpha =1- ((64- offsetY) /64);self.navigationController.navigationBar.backgroundColor= [color colorWithAlphaComponent:alpha];? ? }else{self.navigationController.navigationBar.backgroundColor= [color colorWithAlphaComponent:0];? ? }}

結(jié)果卻是条霜。催什。。

仔細(xì)觀察宰睡,會(huì)發(fā)現(xiàn)navigationBar的高度是44蒲凶,它的上方是statusBar,而且拆内,navigationBar的上面還有一個(gè)未知的View旋圆。。麸恍。到底Apple是怎么實(shí)現(xiàn)UINavigationBar的呢灵巧,讓我們一探究竟搀矫!

在xcode的頂部菜單欄找到Debug > View Debugging > Capture View Hierarchy:

原來UINavigationBar上有一個(gè)_UIBackDropView,正是它決定了navigationBar的背景色刻肄。

那么我們是不是可以修改它的顏色呢瓤球,趕緊打開UINavigationBar.h,找了一圈敏弃,??

既然沒有public的API卦羡,我們只能hack了!

Hack

我們的思路很簡(jiǎn)單麦到,參照Apple的實(shí)現(xiàn)绿饵,在navigationBar的view hierarchy中插入一個(gè)view,通過它來控制在navigationBar的backgroundColor隅要。

考慮到繼承UINavigationBar使用起來會(huì)非常不便蝴罪,我們決定用Category來實(shí)現(xiàn),首先定義我們的category:

@interfaceUINavigationBar(BackgroundColor)- (void)lt_setBackgroundColor:(UIColor*)backgroundColor;@end

實(shí)現(xiàn):我們使用associatedObject將overlayView動(dòng)態(tài)地綁定到UINavigationBar的instance上步清,當(dāng)調(diào)用lt_setBackgroundColor的時(shí)候要门,我們只要更新這個(gè)overlayView就行啦~

@implementationUINavigationBar(BackgroundColor)staticcharoverlayKey;- (UIView*)overlay{returnobjc_getAssociatedObject(self, &overlayKey);}- (void)setOverlay:(UIView*)overlay{? ? objc_setAssociatedObject(self, &overlayKey, overlay, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (void)lt_setBackgroundColor:(UIColor*)backgroundColor{if(!self.overlay) {? ? ? ? [selfsetBackgroundImage:[UIImagenew] forBarMetrics:UIBarMetricsDefault];? ? ? ? [selfsetShadowImage:[UIImagenew]];// insert an overlay into the view hierarchyself.overlay= [[UIViewalloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width,64)];? ? ? ? [selfinsertSubview:self.overlayatIndex:0];? ? }self.overlay.backgroundColor= backgroundColor;}@end

最后在scrollViewDidScroll中,我們就可以動(dòng)態(tài)地修改UINavigationBar的backgroundColor了:

[self.navigationController.navigationBar lt_setBackgroundColor:[color colorWithAlphaComponent:alpha]];

完整的代碼在這里:https://github.com/ltebean/LTNavigationBar

寫在最后

UINavigationBar是一個(gè)比較特殊的view廓啊,它被系統(tǒng)高度集成欢搜,有時(shí)候定制起來并不那么方便。其實(shí)這個(gè)demo完全可以用另外一種方法實(shí)現(xiàn)谴轮,就是不用UINavigationBar炒瘟,自己畫一套UI。

很多時(shí)候我們都會(huì)發(fā)現(xiàn)系統(tǒng)原生控件出現(xiàn)一些預(yù)料之外的行為第步,那么打開view debugging疮装,找出原因,然后解決它粘都!

leo

Readmore postsby this author.

Share this post

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末廓推,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子翩隧,更是在濱河造成了極大的恐慌樊展,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堆生,死亡現(xiàn)場(chǎng)離奇詭異专缠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)淑仆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門涝婉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蔗怠,你說我怎么就攤上這事嘁圈∈÷睿” “怎么了蟀淮?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵最住,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我怠惶,道長(zhǎng)涨缚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任策治,我火速辦了婚禮脓魏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘通惫。我一直安慰自己茂翔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布履腋。 她就那樣靜靜地躺著珊燎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪遵湖。 梳的紋絲不亂的頭發(fā)上悔政,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音延旧,去河邊找鬼谋国。 笑死,一個(gè)胖子當(dāng)著我的面吹牛迁沫,可吹牛的內(nèi)容都是我干的芦瘾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼集畅,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼近弟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起牡整,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤藐吮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后逃贝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谣辞,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年沐扳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泥从。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沪摄,死狀恐怖躯嫉,靈堂內(nèi)的尸體忽然破棺而出纱烘,到底是詐尸還是另有隱情,我是刑警寧澤祈餐,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布擂啥,位于F島的核電站,受9級(jí)特大地震影響帆阳,放射性物質(zhì)發(fā)生泄漏哺壶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一蜒谤、第九天 我趴在偏房一處隱蔽的房頂上張望山宾。 院中可真熱鬧,春花似錦鳍徽、人聲如沸资锰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绷杜。三九已至,卻和暖如春胖翰,著一層夾襖步出監(jiān)牢的瞬間接剩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工萨咳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留懊缺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓培他,卻偏偏與公主長(zhǎng)得像鹃两,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子舀凛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容