1. 程式人生 > >45.自定義導航欄 UINavigationBar

45.自定義導航欄 UINavigationBar

1.改變導航欄風格
可以通過程式碼修改也可以通過 plist修改

@property(nonatomic,assign) UIBarStyle barStyle __TVOS_PROHIBITED;

typedef NS_ENUM(NSInteger, UIBarStyle) {
    UIBarStyleDefault          = 0,
    UIBarStyleBlack            = 1,
    UIBarStyleBlackOpaque      = 1, // Deprecated. Use UIBarStyleBlack
    UIBarStyleBlackTranslucent = 2
, // Deprecated. Use UIBarStyleBlack and set the translucent property to YES } __TVOS_PROHIBITED;

只有 defaul 和 black 兩種, 預設是default 白底黑字半透明的, balack是黑底白字半透明.
效果如下:
這裡寫圖片描述

self.navigationController.navigationBar.barStyle = UIBarStyleBlack;

2.改變導航欄背景顏色(barTintColor)

@property(nullable, nonatomic,strong) UIColor *barTintColor NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; // default is nil

//self.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
self.navigationController.navigationBar.barTintColor = [UIColor cyanColor];

此屬性預設為 nil, 所有預設是半透明的, 當設定顏色後, 變為不透明顏色.
效果如下:
這裡寫圖片描述

3.改變導航欄渲染色(titnColor)

@property(null_resettable, nonatomic,strong) UIColor *tintColor;

self.navigationController.navigationBar.tintColor = [UIColor purpleColor];

此屬性只能影響導航欄上的按鈕的顏色,效果如下:
這裡寫圖片描述

4.改變title 字型顏色

    [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor orangeColor], NSFontAttributeName:[UIFont systemFontOfSize:20.0f]}];

這裡寫圖片描述

5.將導航欄以圖片為背景

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

對於導航欄設定背景圖片有一些需要注意的地方:
/* navigationBar豎屏下預設高度44,橫屏下預設高度32
對於 navigationBar 背景圖片的問題,對尺寸有嚴格的要求(豎屏來說):
1.當圖片高度小於44或者大於64時,會對 nabigationBar 以及 statusBar 同時附上圖片,並且是平鋪效果
2.當圖片高度等於44時,只會給 navigationBar 附上圖片,不會對 statusBar 做任何修改
3.當圖片高度等於64時,會對 navigaBar 和 statusBar 同時附上圖片
*/

6.改變導航欄透明狀態

@property(nonatomic,assign,getter=isTranslucent) BOOL translucent NS_AVAILABLE_IOS(3_0) UI_APPEARANCE_SELECTOR; // Default is NO on iOS 6 and earlier. Always YES if barStyle is set to UIBarStyleBlackTranslucent

注意:
iOS6及之前預設為不透明, 之後就預設為透明的了. 這也是為什麼 iOS6和 iOS7在新增檢視時, frame 不一致需要適配的區別之處.
1.因為navigationBar在透明情況,與contentView會重合一部分割槽域。在不透明情況,contentView緊挨在navigationBar的下⾯. 具體導航欄對佈局的影響可以參考我其他的文章:41.影響iOS6與iOS7螢幕適配的引數和因素40.iOS6與iOS7螢幕適配 edgesForExtendedLayout
2.且當透明狀態的時候,設定背景圖片時,其預設的平鋪效果就會消失.

self.navigationController.navigationBar.translucent = NO;
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
view.backgroundColor = [UIColor greenColor];
[self.view addSubview:view];

效果圖對比:
這裡寫圖片描述

導航欄完全透明設定:

[self.navigationController setNavigationBarHidden:YES];
//[self.navigationController setNavigationBarHidden:YES animated:YES];

或者

//導航欄透明
self.navigationController.navigationBar.translucent = YES;
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];

效果圖:
這裡寫圖片描述
也許你會看到一條黑色的線條, 它其實是一個陰影, 去除陰影請看下面: 11.預設導航欄下面會有一個陰影如何去除

7.新增多個欄按鈕專案

    UIBarButtonItem *shareItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:nil];
    UIBarButtonItem *cameraItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:nil];
    NSArray *itemsArr = @[shareItem,cameraItem];
    self.navigationItem.rightBarButtonItems = itemsArr;

效果如下:
這裡寫圖片描述

8.自定義後退按鈕(backBarButtonItem)
通常情況下,我們使用UINavigationController時,push到的子頁面,左上角會是系統自動取值上一層父頁面的title名稱.
通過設定navigationItem的backBarButtonItem可以直接更換文字,【注意,要在父檢視的Controller中設定】如下:

    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"自定義" style:UIBarButtonItemStylePlain target:nil action:nil];
    self.navigationItem.backBarButtonItem = item;

效果如下:
這裡寫圖片描述
如果不想顯示文字,直接”“,就會單獨顯示一個系統的返回箭頭圖示. 但需要注意的是, 所有當前控制器 push 出的子介面返回時都變成了我們定義的文字.

9.leftBarButtonItem和backBarButtonItem優先順序及backItem
先說一下 backItem, navigationBar.backItem是一個只讀屬性,不能設定。
navigationcontroller按照以下3條順序更改導航欄的左側按鈕:
1、如果B檢視有一個自定義的左側按鈕(leftBarButtonItem),則會顯示這個自定義按鈕;
2、如果B沒有自定義按鈕,但是A檢視的backBarButtonItem屬性有自定義項,則顯示這個自定義項;
3、如果前2條都沒有,則預設顯示一個後退按鈕,後退按鈕的標題是A檢視的標題;

10.導航欄的返回手勢(interactivePopGestureRecognizer)

這是在iOS7中新增加的屬性, 這個功能就是在NavigationController堆疊內的UIViewController可以支援右滑手勢,也就是不用點選右上角的返回按鈕,輕輕在螢幕左邊一滑,螢幕就會返回。預設是 YES,是開啟的.

self.navigationController.interactivePopGestureRecognizer.enabled = YES;

需要注意的是, 自定義backVarButtonItem 時, 它便會失效, 一下是解決方法:
這個功能是好,但是經常我們會有需求定製返回按鈕,如果手動定製了返回按鈕,這個功能將會失效,也就是自定義了navigationItem的leftBarButtonItem,那麼這個手勢就會失效。解決方法找到兩種
1.重新設定手勢的delegate
self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
2.當然你也可以自己響應這個手勢的事件
[self.navigationController.interactivePopGestureRecognizer addTarget:self action:@selector(handleGesture:)];

11.預設導航欄下面會有一個陰影如何去除
這個是在實戰中遇到的, 用盡了其他的方法不管用, 置為 nil 也不管用, 只可以 alloc init 出一個image 來.

self.navigationController.navigationBar.shadowImage = [[UIImage alloc]init];