UINavigationBar 使用總結

 

UINavigationBar是咱們在開發過程當中常常要用到的一個控件,下面我會爲你們介紹一些經常使用的用法。html

1. 設置導航欄的標題

這個很少說,直接上代碼
self.navigationItem.title = @"UINavigationBar使用總結";ios

2. 設置導航欄的背景顏色

//經過barTintColor來設置背景色
 self.navigationController.navigationBar.barTintColor = [UIColor redColor];

獲得的效果以下:git

Snip20150912_1.pnggithub

barTintColor: 這個屬性須要在iOS7以上纔可使用; 若是要支持iOS6以及如下的系統,能夠參考這篇文章:UINavigationBar Background Color 微信

3. 設置導航欄的背景圖片

除了經過設置背景顏色來改變導航欄的外觀外,咱們還能夠經過背景圖片來設置導航欄的外觀。app

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"Background"]
                                                  forBarMetrics:UIBarMetricsDefault];

Snip20150912_2.pngide

在這裏得稍微說說UIBarMetrics這個枚舉, 它主要是用來控制在不一樣狀態下導航欄的顯示。和UIButton的
- (void)setBackgroundImage:(nullable UIImage *)image forState:(UIControlState)state這個方法有點相似。字體

//表示橫屏豎屏都顯示
UIBarMetricsDefault,
//表示在只橫屏下才顯示,和UIBarMetricsLandscapePhone功效同樣,不過iOS8已經棄用了
UIBarMetricsCompact,
UIBarMetricsDefaultPrompt和UIBarMetricsCompactPrompt這兩個我還沒搞清楚是什麼意思,有知道的朋友不妨給咱們來普及一下。。ui

4. 更改頂部狀態欄的顏色

從效果圖能夠看出,咱們設置背景色或者背景圖以後,狀態欄依然仍是默認的黑色,這樣感受很差看。好在,系統給咱們提供了UIStatusBarStyleDefaultUIStatusBarStyleLightContent兩種樣式供咱們選擇。spa

  • UIStatusBarStyleDefault,系統的默認樣式,黑色內容,用於淺色的背景(如白色)
  • UIStatusBarStyleLightContent 白色內容,用於深色的背景(如紅色)

下面來看看具體怎麼實現,主流的實現方式是分兩步:

  1. 在工程的Info.plist文件中添加一行UIViewControllerBasedStatusBarAppearance,選擇Boolean類型,並設置爲YES,Xcode會自動把名稱變爲View controller-based status bar appearance。

    Snip20150913_4.png

  2. 在你的ViewController中添加下面的方法
    -(UIStatusBarStyle)preferredStatusBarStyle{
     return UIStatusBarStyleLightContent;
    }

想知道更多地方式,能夠參考這兩個頁面:How to change Status Bar text color in iOS 7 和 iOS7下Status Bar字體顏色修改

另外,特別須要注意的是,若是你的ViewController是經過navigationController push進來的,還須要加下面一句代碼才能生效:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
具體,可參考UIStatusBarStyle PreferredStatusBarStyle does not work on iOS 7

恩,咱們來看看運行效果。

Snip20150913_5.png

5. 設置返回按鈕

從上面的效果圖中咱們能夠看到返回按鈕仍是默認的藍色按鈕,下面我將會你們來介紹返回按鈕的個性化。

  • 設置返回按鈕的顏色
    只須要設置tintColor屬性便可
    self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
    獲得的效果圖以下:

    Snip20150915_1.png

  • 只設置返回按鈕的圖片
- (void)goToBack {
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)setBackButtonWithImage {
    UIImage *leftButtonIcon = [[UIImage imageNamed:@"LeftButton_back_Icon"]
                               imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithImage:leftButtonIcon
                                                                   style:UIBarButtonItemStyleBordered
                                                                  target:self
                                                                  action:@selector(goToBack)];
    self.navigationItem.leftBarButtonItem = leftButton;

    //修復navigationController側滑關閉失效的問題
    self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
}

獲得的效果以下:

Snip20150915_2.png

這裏須要注意的地方有三點:

  1. 須要本身實現返回按鈕的事件。
  2. 特別的解釋下UIImage的imageWithRenderingMode:方法,參數UIImageRenderingModeAlwaysOriginal 表示老是用原圖渲染,若是不這麼設置,返回按鈕將會顯示tintColor的顏色(默認爲藍色)。UITabbarItem也存在一樣地問題。 
  3. 咱們本身設置返回按鈕,會致使系統的側滑關閉效果失效。添加上面代碼中最後一句代碼便可修復。
  • 僅設置返回按鈕的文字
- (void)setBackButtonTitle {
    UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"取消", nil)
                                                                   style:UIBarButtonItemStylePlain
                                                                  target:self action:@selector(goToBack)];
    leftButton.tintColor = [UIColor whiteColor];
    self.navigationItem.leftBarButtonItem = leftButton;
}

獲得的效果以下:

Snip20150915_3.png

  • 自定義返回按鈕
    若是上面幾種方式還沒法知足你的要求(好比,須要同時設置返回按鈕文字和圖片),就須要用到UIBarButtonIteminitWithCustomView方法。
- (void)setCustomLeftButton {
    UIView* leftButtonView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 60, 40)];
    UIButton* leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
    leftButton.backgroundColor = [UIColor clearColor];
    leftButton.frame = leftButtonView.frame;
    [leftButton setImage:[UIImage imageNamed:@"LeftButton_back_Icon"] forState:UIControlStateNormal];
    [leftButton setTitle:@"返回" forState:UIControlStateNormal];
    leftButton.tintColor = [UIColor redColor];
    leftButton.autoresizesSubviews = YES;
    leftButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    leftButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;
    [leftButton addTarget:self action:@selector(goToBack) forControlEvents:UIControlEventTouchUpInside];
    [leftButtonView addSubview:leftButton];
    UIBarButtonItem* leftBarButton = [[UIBarButtonItem alloc] initWithCustomView:leftButtonView];
    self.navigationItem.leftBarButtonItem = leftBarButton;
}

獲得的效果圖以下:

Snip20150915_5.png

設置rightBarButtonItem基本上脫離不了上面的幾種方式,你們能夠參照上面返回按鈕的設置方式。

6. 隱藏導航欄底部的線條

有時候遇到一些特殊的要求,須要隱藏導航欄底部的線條。
兩行代碼就能夠作到。

  • 設置導航欄的背景圖(setBackgroundImage方法)
  • 設置導航欄的shadowImage (setShadowImage方法)
UINavigationBar *navigationBar = self.navigationController.navigationBar;
    //設置透明的背景圖,便於識別底部線條有沒有被隱藏
    [navigationBar setBackgroundImage:[[UIImage alloc] init]
                       forBarPosition:UIBarPositionAny
                           barMetrics:UIBarMetricsDefault];
    //此處使底部線條失效
    [navigationBar setShadowImage:[UIImage new]];

來看看效果圖:

Snip20150922_1.png

另外,還有一種作法,一行代碼就能夠達到效果,也真是夠神奇的。。

//方法二:
    self.navigationController.navigationBar.clipsToBounds = YES;

想要知道更詳細的內容能夠參考這個頁面:How to hide iOS7 UINavigationBar 1px bottom line

7. 設置導航條底部線條的顏色

有了上面的基礎,設置導航欄線條的顏色就變得很簡單了。
首先,我作了個UIImage的分類:經過顏色轉成UIImage;
而後,用上面的方案來設置導航欄底部線條。

顏色轉圖片的代碼:

@implementation UIImage (ColorImage)

+ (UIImage *)imageWithColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

@end

設置導航欄底部線條顏色的代碼:

UINavigationBar *navigationBar = self.navigationController.navigationBar;
    [navigationBar setBackgroundImage:[[UIImage alloc] init]
                       forBarPosition:UIBarPositionAny
                           barMetrics:UIBarMetricsDefault];
    //此處使底部線條顏色爲紅色
    [navigationBar setShadowImage:[UIImage imageWithColor:[UIColor redColor]]];

依照慣例,看下效果圖:

Snip20150923_2.png

固然還有其餘的方式也能夠作到,如addSubview, addSubLayer等。感興趣的話能夠參考下這個頁面:iOS7 - Change UINavigationBar border color

8. 在導航欄上添加多個按鈕

以微信打開網頁時的效果爲例,效果圖以下,有兩個按鈕:返回和關閉。

微信效果圖.png


有下面兩種方式可供選擇,可是最終仍是要用到leftBarButtonItems這個方法。

#define UserMethod1 0

    UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithTitle:@"關閉" style:UIBarButtonItemStylePlain target:self action:@selector(closeAction)];
    if (UserMethod1) {
        //方法一:
        self.navigationItem.leftBarButtonItems = @[closeItem];
        //要求顯示默認的返回按鈕,可是文字會顯示默認的Back,暫時還不知道這個文字怎麼改
        self.navigationItem.leftItemsSupplementBackButton = YES;
    }
    else {
        //方法二
        UIButton* leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
        leftButton.backgroundColor = [UIColor clearColor];
        leftButton.frame = CGRectMake(0, 0, 45, 40);
        [leftButton setImage:[UIImage imageNamed:@"LeftButton_back_Icon"] forState:UIControlStateNormal];
        [leftButton setTitle:@"返回" forState:UIControlStateNormal];
        leftButton.tintColor = [UIColor whiteColor];
        leftButton.autoresizesSubviews = YES;
        leftButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
        leftButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;
        [leftButton addTarget:self action:@selector(goToBack) forControlEvents:UIControlEventTouchUpInside];
        UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];

        self.navigationItem.leftBarButtonItems = @[backItem,closeItem];
    }

而後,運行的效果圖以下:

在導航欄上添加多個按鈕.png

方法一用到了leftItemsSupplementBackButton 這個屬性,會顯示系統默認的返回按鈕,可是文字也是顯示默認的Back文字,目前還沒找到怎麼修改這個文字,若是有誰知道,還請不吝賜教;因此我暫時仍是建議你們用方法二。相應的還有 rightBarButtonItems這個屬性,若是要在導航欄右側展現多個按鈕的話,能夠設置這個屬性。

9. 在導航欄上添加分段控件

此次,以QQ爲例,代碼以下:

UISegmentedControl *segControl = [[UISegmentedControl alloc] initWithItems:@[@"消息",@"電話"]];
    segControl.tintColor = [UIColor colorWithRed:0.07 green:0.72 blue:0.96 alpha:1];
    [segControl setSelectedSegmentIndex:0];
    self.navigationItem.titleView = segControl;

代碼很簡單,就是設置titleView這個屬性,固然,你也能夠把這個屬性設置爲你自定義的View。

相似於QQ的導航欄.png

10. 導航欄全局屬性設置

//全局設置導航欄主題
- (void)setNavigationControllerAppearance {
    [UINavigationBar appearance].barStyle  = UIBarStyleBlack;
    [[UINavigationBar appearance] setBarTintColor:[UIColor colorWithWhite:0.1 alpha:0.5]];
    [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
}

全局設置導航欄的好處有兩個:一是不用對每一個NavigationBar進行設置;二是方便作主題管理,切換主題,只須要更改全局設置便可。

11. 與導航欄相關的一些開源組件

11.1 NJKWebViewProgress - 相似於Safiri加載網頁時的進度顯示

網頁加載進度.png

11.2 FDFullscreenPopGesture - 一個絲滑的全屏滑動返回手勢

對應的文章介紹能夠點這個連接

絲滑的全屏返回手勢.png

最後,奉上Demo的地址:NavigationBarDemo

相關文章
相關標籤/搜索