iOS --沒事擼一擼控件之UINavigationBar

UINavigationBar江锨,只要是做iOS開發(fā)的肯定都碰到過闻牡。今天趁著手頭的沒有磚可搬盗似,好好整理一下酱塔。

層級(jí)關(guān)系

首先寫一個(gè)簡單的UINavigationController沥邻,查看視圖層級(jí)⊙蛲蓿可以看到下面的層級(jí)關(guān)系唐全。

F0629251-5F4D-4347-A585-F8B6C7BD390F.png

第一級(jí) UINavigationBar

這沒什么好說的,今天的主角蕊玷。

第二級(jí)

_UINavigationBarBackground(UIImageView)

這個(gè)對(duì)應(yīng)了bar 的背景圖片方法邮利,不過這個(gè)屬性不屬于共有API

- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;

UINavigationButton

這個(gè)就是我們自定義的btn

_UINaigationBarBackIndicatorView

這個(gè)就是返回按鈕,可以自定義圖片

@property(nullable,nonatomic,strong) UIImage *backIndicatorImage NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR __TVOS_PROHIBITED;

第三級(jí) 第四級(jí)----

這邊我們主要來看下系統(tǒng)的_UINavigationBarBackground 下面的層級(jí)垃帅,
首先近弟,我們看到在第三級(jí)別里面有個(gè)UIImageView.這個(gè)imageview 其實(shí)是bar下面的深灰色一條線。
我記得我一個(gè)基友挺智,來問我這個(gè)問題祷愉,說要把下面這條線隱藏。我費(fèi)了老大的力氣赦颇,才找到這個(gè)私有屬性名二鳄。看下面代碼媒怯! 就是這個(gè) _shadowView

 UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];
    NSArray *arry = [nav.navigationBar subviews];
    for (UIView *view in arry) {
        NSString *viewName = NSStringFromClass([view class]);
        if ([viewName isEqualToString:@"_UINavigationBarBackground"]) {
            UIImageView *line = [view valueForKey:@"_shadowView"];
            line.hidden = YES;
        }
    }
    self.window.rootViewController = nav;

畢竟私有屬性订讼,比較好的方法就是用別的view蓋住他。但直接使用這個(gè)屬性隱藏扇苞,好像基友的應(yīng)用也是ok的欺殿。

話題有點(diǎn)偏了,我們繼續(xù)回到正題上鳖敷。
還有一個(gè)_UIBackDropView 和_UIBackdropEffectView
這個(gè)其實(shí)就是系統(tǒng)加的毛玻璃效果脖苏。

我們肯定遇到要設(shè)置NavigationBar 背景顏色的時(shí)候
如果想平常的空間一樣

self.navigationController.navigationBar.backgroundColor = [UIColor blackColor];

那么恭喜你掉坑里了,如何正確設(shè)置定踱。以及為什么要這么設(shè)置我們下面一一道來棍潘。

突變的層級(jí)結(jié)構(gòu)

CA7AC3B0-E41E-4D4B-A3D0-32E72777BDD8.png

當(dāng)我們?cè)O(shè)置了背景圖片,臥槽。第三和第四級(jí)的那2個(gè)view呢亦歉。系統(tǒng)在你設(shè)置背景圖片的時(shí)候自定將有毛玻璃效果的2個(gè)層級(jí)恤浪,從視圖上移除。讓我們可以清楚的看到背景肴楷。
但你設(shè)置背景顏色時(shí)候水由,那2個(gè)層級(jí)還在。不知道蘋果baba 是怎么想的赛蔫。

[self.navigationController.navigationBar setBackgroundImage:[UIImage new]forBarMetrics:UIBarMetricsDefault];
    self.navigationController.navigationBar.backgroundColor = [UIColor redColor];

這樣就可以完美的設(shè)置背景色了砂客。
其實(shí)系統(tǒng)也提供了設(shè)置全局bar的方法了

[[UINavigationBar appearance] setBackgroundColor:[UIColor redColor]];

這種也可以成功的bar 的背景色。不過是全局的濒募。

--了解NavigationBar 的層次結(jié)構(gòu),我們就針對(duì)大多數(shù)問題 做一個(gè)解答圾结。
Q:怎么設(shè)置NavigationBar 的背景色
上面已經(jīng)說過了瑰剃,就不說啦
Q:我想設(shè)置NavigationBar 透明,但我想item不隱藏筝野。
首先我們看下層次結(jié)構(gòu) 晌姚,如果你這樣設(shè)置

self.navigationController.navigationBar.alpha = NO;

肯定不行歇竟,我們知道如果設(shè)置背景色挥唠,是第二級(jí)的_UINavigationBarBackground 來顯示的,而UINavationBarButton 和他平級(jí)焕议。知道這一點(diǎn)就好做了啊宝磨。只要設(shè)置_UINavigationBarBackground 的alpha 為0 就可以了。
不過要注意一點(diǎn)盅安,因?yàn)樘O果沒開放這個(gè)屬性唤锉。所以為了安全過過審起見,可以這樣設(shè)置:

[self.navigationController.navigationBar subViews][0] //這個(gè)就是_UINavigationBarBackground 設(shè)置透明度就好啦别瞭。

Q:我想設(shè)置nagationBar 滑動(dòng)漸變效果
如果我根據(jù)滑動(dòng)的偏移量來設(shè)置 _UINavigationBarBackground的透明度窿祥。那就掉坑了,還記得3 4層級(jí)的毛玻璃效果么蝙寨,只有當(dāng)_UINavigationBarBackground 完全透明或者設(shè)置背景圖片的時(shí)候才會(huì)隱藏晒衩。
這就說明,你滑動(dòng)的時(shí)候毛3 4層級(jí)還在墙歪,你漸變的效果被3.4 層級(jí)覆蓋住了听系。就看不到你想要的效果了。
我們一步一步 來:
首先要去掉3 4 層級(jí) (系統(tǒng)的毛玻璃效果)

[self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
或者
[self.navigationController.navigationBar subViews][0] .alpha = 0;

3 4層級(jí)去掉了 漸變效果怎么顯示昂绶啤跛锌!
這時(shí)候因?yàn)橐∠? 4層級(jí) 占用了系統(tǒng)自帶的設(shè)置背景色的view。我們可以自己創(chuàng)建一個(gè)view來顯示背景色。大體思路就是這樣髓帽。借用別人的一段代碼

static char overlayKey;

- (UIView *)overlay
{
    return objc_getAssociatedObject(self, &overlayKey);
}

- (void)setOverlay:(UIView *)overlay
{
    objc_setAssociatedObject(self, &overlayKey, overlay, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)lt_setBackgroundColor:(UIColor *)backgroundColor
{
    if (!self.overlay) {
        [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
        self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) + 20)];
        self.overlay.userInteractionEnabled = NO;
        self.overlay.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        [self insertSubview:self.overlay atIndex:0];
    }
    self.overlay.backgroundColor = backgroundColor;
}

只要了解了層次結(jié)構(gòu)菠赚,大部分的問題都迎刃而解。如果童鞋們郑藏,還有什么問題衡查,可以留言,我以后跟新補(bǔ)充必盖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拌牲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子歌粥,更是在濱河造成了極大的恐慌塌忽,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件失驶,死亡現(xiàn)場離奇詭異土居,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嬉探,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門擦耀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涩堤,你說我怎么就攤上這事眷蜓。” “怎么了胎围?”我有些...
    開封第一講書人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵吁系,是天一觀的道長。 經(jīng)常有香客問我白魂,道長垮抗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任碧聪,我火速辦了婚禮冒版,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逞姿。我一直安慰自己辞嗡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開白布滞造。 她就那樣靜靜地躺著续室,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谒养。 梳的紋絲不亂的頭發(fā)上挺狰,一...
    開封第一講書人閱讀 49,856評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼丰泊。 笑死薯定,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的瞳购。 我是一名探鬼主播话侄,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼学赛!你這毒婦竟也來了年堆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤盏浇,失蹤者是張志新(化名)和其女友劉穎变丧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绢掰,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痒蓬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了曼月。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谊却。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡柔昼,死狀恐怖哑芹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布辣苏,位于F島的核電站射窒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏漏设。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盟榴。 院中可真熱鬧,春花似錦婴噩、人聲如沸擎场。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迅办。三九已至,卻和暖如春章蚣,著一層夾襖步出監(jiān)牢的瞬間站欺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留矾策,地道東北人磷账。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像蝴韭,于是被迫代替她去往敵國和親够颠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349