UINavigationBar江锨,只要是做iOS開發(fā)的肯定都碰到過闻牡。今天趁著手頭的沒有磚可搬盗似,好好整理一下酱塔。
層級(jí)關(guān)系
首先寫一個(gè)簡單的UINavigationController沥邻,查看視圖層級(jí)⊙蛲蓿可以看到下面的層級(jí)關(guān)系唐全。
第一級(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)
當(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ǔ)充必盖。