動態修改NavigationBar的顏色


轉: http://www.jianshu.com/p/6f3bc1da18f3


動態修改NavigationBar的顏色
字數785 閱讀2269 評論4 喜歡9
如果我們想動態的修改NavigationBar的顏色會腫麼做呢?
首先我們想到的肯定是在UISrollView的delegate方法

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

根據當前的contentOffset更新navigationBar的backgroundColor即可.

思路
首先想到的是最常用的[UINavigationBar appearance],我們一般會在AppDelegate中使用它對navigationBar進行統一的設置。但是如果試一下,會發現在scrollViewDidScrollView中調用它並不能動態地改變navigationBar的顏色,原因是: iOS應用出現變化時,視圖會進入一個窗口,它不能改變已經再一個窗口的外觀。

我們換一個方法試試看,直接修改UINavigationBar的backgroudColor:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
UIColor *color = [UIColor redColor];
CGFloat offsetY = scrollView.contentOffset.y;
if (offsetY > 0) {
    CGFloat alpha = 1 - ((64 - offsetY) / 64);
    self.navigationController.navigationBar.backgroundColor = [color colorWithAlphaComponent:alpha];
} else {
     self.navigationController.navigationBar.backgroundColor = [color colorWithAlphaComponent:0];
        }
}
然後發現,怎麼是。。。。。有一半咋沒有顏色 ????這是神馬情況???


通過reveal查看其中的層級結構,發現NavigationBar上面有一個_UINavigationBarBackground的遮蓋,正是它決定了navigationBar的背景色。


那我們把這個view拿到,刪除不就可以了麼?繼續嘗試。

我們通過打印 self.navigationController.navigationBar.subviews看到navigationBar上有兩個子控件。

"<_UINavigationBarBackground: 0x7fed90f43990; frame = (0 -20; 414 64); opaque = NO; autoresize = W;                     userInteractionEnabled = NO; layer = <CALayer: 0x7fed90f36a90>>",
"<_UINavigationBarBackIndicatorView: 0x7fed90d053f0; frame = (0 11.6667; 13 21); alpha = 0; opaque = NO;             userInteractionEnabled = NO; layer = <CALayer: 0x7fed90dc6e50>>"
我們可以通過遍歷把 _UINavigationBarBackground 拿到並刪除即可

for (UIView *view in self.navigationController.navigationBar.subviews) {
    if ([view isKindOfClass:NSClassFromString(@"_UINavigationBarBackground")]) {
        [view removeFromSuperview];
    }
}
然後發現這樣就可以了,不過狀態欄還是白色的啊~~~


這時我們改變下狀態欄的顏色就好了,要修改狀態欄的顏色比較麻煩,那我們可以直接在navigationBar上加上一層遮罩就好

UIView *overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width,20)];
overlay.backgroundColor = [UIColor redColor];
[self.navigationController.navigationBar insertSubview:overlay atIndex:0];
不過這麼幹的話,那就要修改兩個控件顏色。。。。這樣修改起來非常的麻煩,有沒有什麼好點的方法呢????

換一個思路
考慮到繼承UINavigationBar使用起來會非常不便,我們決定用Category來實現,首先定義我們的category:

@interface UINavigationBar (BackgroundColor)
- (void)lt_setBackgroundColor:(UIColor *)backgroundColor;
@end
我們可以使用associatedObject將overlay動態地綁定到UINavigationBar的instance上,當調用lt_setBackgroundColor的時候,我們只要更新這個overlay就可以了

   static char overlayKey;
@implementation UINavigationBar (BackgroundColor)


- (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 setShadowImage:[UIImage new]];             
    self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width, 64)];
    [self insertSubview:self.overlay atIndex:0];  
}   
        self.overlay.backgroundColor = backgroundColor;
}
@end
最後在scrollViewDidScroll中,我們就可以動態地修改UINavigationBar的backgroundColor了:

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

這個方法是參考了 LTNavigationBar 第三方類庫,這類庫已經給我們封裝好了這些方法,使用起來非常簡單

詳情請點這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章