你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 動態修改UINavigationBar的背景色

動態修改UINavigationBar的背景色

編輯:IOS開發基礎

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

1428390275361373.gif

思路

在UISrollView的delegate方法

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView

中根據當前的contentOffset更新navigationBar的backgroundColor即可,so easy~

開動

那麼我們來看看apple為我們提供了哪些API來設置navigationBar的顏色。

首先想到的是最常用的[UINavigationBar appearance],我們一般會在AppDelegate中使用它對navigationBar進行統一的設置。但是如果試一下,會發現在scrollViewDidScrollView中調用它並不能動態地改變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 = [UIColor blueColor];
    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];
    }
}

結果卻是……

2.jpg

仔細觀察,會發現navigationBar的高度是44,它的上方是statusBar,而且,navigationBar的上面還有一個未知的View……到底Apple是怎麼實現UINavigationBar的呢,讓我們一探究竟!

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

1428390599183114.jpg

1428390603214036.jpg

原來UINavigationBar上有一個_UIBackDropView,正是它決定了navigationBar的背景色。

那麼我們是不是可以修改它的顏色呢,趕緊打開UINavigationBar.h,找了一圈,1428390838630372.jpg

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

Hack

我們的思路很簡單,參照Apple的實現,在navigationBar的view hierarchy中插入一個view,通過它來控制在navigationBar的backgroundColor。

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

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

實現:我們使用associatedObject將overlayView動態地綁定到UINavigationBar的instance上,當調用lt_setBackgroundColor的時候,我們只要更新這個overlayView就行啦~

@implementation UINavigationBar (BackgroundColor)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 setShadowImage:[UIImage new]];        // insert an overlay into the view hierarchy
        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]];

完整的代碼在這裡

寫在最後

UINavigationBar是一個比較特殊的view,它被系統高度集成,有時候定制起來並不那麼方便。其實這個demo完全可以用另外一種方法實現,就是不用UINavigationBar,自己畫一套UI。

很多時候我們都會發現系統原生控件出現一些預料之外的行為,那麼打開view debugging,找出原因,然後解決它!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved