UINavigationBar詳細(xì)指南

1.UINavigationBar和UINavigationItem

UINavigationItem : NSObject

When building a navigation interface, each view controller pushed onto the 
navigation stack must have a `UINavigationItem` object that contains the 
buttons and views it wants displayed in the navigation bar. The 
managing UINavigationController object uses the navigation items of the 
topmost two view controllers to populate the navigation bar with content.

當(dāng)view controller push進(jìn)入navigation stack的時(shí)候,UINavigationItem是必須存在的倡勇,通常navigationController已經(jīng)自動創(chuàng)建了UINavigationItem枢劝,它負(fù)責(zé)管理UInavigationController中的item和Title的內(nèi)容以及交互益楼。

UINavigationBar :UIView<UIBarPositioning>

A UINavigationBar object is a bar, typically displayed at the top of the 
window, containing buttons for navigating within a hierarchy of screens. 
The primary components are a left (back) button, a center title, and an 
optional right button. You can use a navigation bar as a standalone object or 
in conjunction with a navigation controller object.

A navigation bar is most commonly used within a navigation controller. 
The object creates, displays, and manages its 
associated navigation bar, and uses attributes of the view controllers you 
add to control the content displayed in the navigation bar.

If you use a navigation controller to manage the navigation between 
different screens of content, the navigation controller creates a navigation 
bar automatically and pushes and pops navigation items when appropriate.

圖片.png

通常情況下我們使用UInavigationController push或者pop一個(gè)viewController的時(shí)候舅踪,UINavigationBar會被自動的創(chuàng)建儡率,UINavigationBar是一個(gè)View的子類毫别,我們可以自定義其顯示的樣式食寡,包括title字體,背景烛恤,顏色等母怜。

關(guān)系

A navigation controller uses the navigationItem property 
on UIViewController to provide the model objects to its navigation bar when 
navigating a stack of view controllers. The default navigation item uses the 
view controller’s title, but you can override the navigationItem on 
a UIViewController subclass to gain complete control 
of the navigation bar’s content.

UINavigationBar的內(nèi)容通常是由navigationItem提供,包括title和items等缚柏,如果想自定義UINavigationBar中的內(nèi)容苹熏,那么需要更改navigationItem的配置。

2.UINavigationBar

UIBarStyle默認(rèn)有4中樣式币喧,translucent屬性設(shè)置bar是否透明轨域。
Bar默認(rèn)帶有毛玻璃效果。

typedef enum UIBarStyle : NSInteger {
    UIBarStyleDefault = 0,
    UIBarStyleBlack = 1,
    UIBarStyleBlackOpaque = 1,
    UIBarStyleBlackTranslucent = 2
} UIBarStyle;

UINavigationBar可以自定義的屬性

Core Attributes : Style , Bar Tint , Shadow Image, Back Image, Back Mask.
Attribute: Title Font, Title Color, Title Shadow.

tip:去除UINavigationBar下方橫線

[self.navigationBar setShadowImage:[[UIImage alloc] init]];
/* 全局 */
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
/* 另外一種方式 */
self.navigationController.navigationBar.clipsToBounds = YES; 

3.UINavigationItem

UINavigationItem提供了API設(shè)置leftItems杀餐,titleView干发,rightItems 和BackItems的方法。

3.1 backBarButtonItem

When this navigation item is immediately below the top item in the stack, 
the navigation controller derives the back button for the navigation bar from 
this navigation item. When this property is `nil`, the navigation item uses 
the value in its title property to create an appropriate back button. If you 
want to specify a custom image or title for the back button, you can assign a 
custom bar button item (with your custom title or image) to this property 
instead. When configuring your bar button item, do not assign a custom 
view to it; the navigation item ignores custom views in the back bar button 
anyway.

backBarButtonItem在UINavigationController中push時(shí)候自動的添加史翘,如果你沒有指定title枉长,則返回按鈕中的文字默認(rèn)是前一個(gè)view controller的title冀续。
不要嘗試去添加custom view,因?yàn)椴粫А?br> hidesBackButton設(shè)置為YES可以隱藏返回按鈕必峰,默認(rèn)是NO洪唐。

The backBarButtonItem property of a navigation item reflects the back 
button you want displayed when the current view controller is just below the 
topmost view controller. In other words, the back button is not used when 
the current view controller is topmost.

If the title of your back button is too long to fit in the available space on the 
navigation bar, the navigation bar may substitute the string “Back” in place 
of the button’s original title. The navigation bar does this only if the back 
button is provided by the previous view controller. If the new top-level view 
controller has a custom left bar button item—an object in the 
leftBarButtonItems or BarButtonItem property of its navigation item—the navigation bar does not change the button title.


你在當(dāng)前View controller中設(shè)置的backBarButtonItem并不是當(dāng)前view中backBarButtonItem的樣式,而是從當(dāng)前view controller中push出的view controller中backBarButtonItem的樣式吼蚁,topmost view controller中backBarButtonItem是無效的凭需。
換而言之,當(dāng)你準(zhǔn)備push一個(gè)view controller并想自定義這個(gè)view controller的backBarButtonItem肝匆,那么在push之前粒蜈,就需要設(shè)置好backBarButtonItem的樣式。

UIViewController *nextViewController = [[UIViewController alloc] initWithNibName:@"" bundle:nil];
//設(shè)置nextViewController中navigationbar的backBtn樣式术唬。
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navBacklIcon"] style:UIBarButtonItemStylePlain target:self action:@selector(Navback)];
[self showViewController:nextViewController sender:nil];

backBarButtonItem的title如果過長則會顯示"back"薪伏。
如果設(shè)置了leftBarButtonItem,則backBarButtonItem將不會顯示粗仓,除非將leftItemsSupplementBackButton設(shè)置為YES,默認(rèn)為NO设捐。
你可以用leftBarButtonItem替代backBarButtonItem借浊,但是backBarButtonItem和leftBarButtonItem的位置是有差異的。

3.自定義UINavigationController

通常一個(gè)項(xiàng)目NavigationBar的風(fēng)格都是統(tǒng)一的萝招,我們可以通過下面方法來設(shè)置全局樣式.

[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
[[UINavigationBar appearance] set........

但是一個(gè)更好的方法是自定義一個(gè)UINavigationController蚂斤。

@interface Q_navigationController ()<UINavigationControllerDelegate,UIGestureRecognizerDelegate>
@end

@implementation Q_navigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self configNavBar];
}
-(void)configNavBar{//全局樣式
    [self.navigationBar setShadowImage:[[UIImage alloc] init]];
    self.navigationBar.translucent = NO;
    self.navigationBar.titleTextAttributes = @{NSFontAttributeName:[UIFont boldSystemFontOfSize:17],
                                               NSKernAttributeName:[NSNumber numberWithInteger:2],
                                               NSForegroundColorAttributeName:[UIColor colorWithRed:18.0/255 green:150.0/255 blue:219.0/255 alpha:1]
                                               };
    self.navigationBar.tintColor = [UIColor colorWithRed:18.0/255 green:150.0/255 blue:219.0/255 alpha:1];
}
@end

UINavigationControllerDelegate是UINavigationController的回調(diào),我們可以在push和pop的時(shí)候收到回調(diào)槐沼,自定義一些需要的事情曙蒸,比如設(shè)置自定義返回按鈕。

-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
    if (navigationController.viewControllers.count > 1) {
        viewController.navigationItem.leftBarButtonItem = self.navBackBtn;
    }
}
-(UIBarButtonItem *)navBackBtn{
    if(!_navBackBtn){
        _navBackBtn =[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navBacklIcon"] style:UIBarButtonItemStylePlain target:self action:@selector(Navback)];
    }
    return _navBackBtn;
}

自定義的UINavigationController也會帶來一些問題岗钩,比如邊緣返回的手勢失效了纽窟,為了能讓它正常的工作,我們還需要做一些工作兼吓,在需要它的時(shí)候?qū)⑵鋏nabled設(shè)置為YES臂港。

- (void)viewDidLoad {
    [super viewDidLoad];
    [self configNavBar];
    
    self.delegate = self;
    self.interactivePopGestureRecognizer.delegate = self;
}

-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
    if (navigationController.viewControllers.count <= 1) {
        self.interactivePopGestureRecognizer.enabled = NO;
    }else{
        self.interactivePopGestureRecognizer.enabled = YES;
    }
}

但是interactivePopGestureRecognizer可能會引入一些手勢沖突問題,比如http://www.reibang.com/p/ffde99688cff中描述的那樣视搏。

總結(jié)

理解UINavigationBar和UINavigationItem的關(guān)系审孽,這讓我們更加優(yōu)雅的設(shè)計(jì)代碼去配置項(xiàng)目中導(dǎo)航欄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浑娜,一起剝皮案震驚了整個(gè)濱河市佑力,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌筋遭,老刑警劉巖打颤,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暴拄,死亡現(xiàn)場離奇詭異,居然都是意外死亡瘸洛,警方通過查閱死者的電腦和手機(jī)揍移,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來反肋,“玉大人那伐,你說我怎么就攤上這事∈幔” “怎么了罕邀?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長养距。 經(jīng)常有香客問我诉探,道長,這世上最難降的妖魔是什么棍厌? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任肾胯,我火速辦了婚禮,結(jié)果婚禮上耘纱,老公的妹妹穿的比我還像新娘敬肚。我一直安慰自己,他們只是感情好束析,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布艳馒。 她就那樣靜靜地躺著,像睡著了一般员寇。 火紅的嫁衣襯著肌膚如雪弄慰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天蝶锋,我揣著相機(jī)與錄音陆爽,去河邊找鬼。 笑死牲览,一個(gè)胖子當(dāng)著我的面吹牛墓陈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播第献,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼贡必,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了庸毫?” 一聲冷哼從身側(cè)響起仔拟,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎飒赃,沒想到半個(gè)月后利花,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體科侈,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年炒事,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了臀栈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挠乳,死狀恐怖权薯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情睡扬,我是刑警寧澤盟蚣,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站卖怜,受9級特大地震影響屎开,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜马靠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一奄抽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧甩鳄,春花似錦如孝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锁孟。三九已至彬祖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間品抽,已是汗流浹背储笑。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留圆恤,地道東北人突倍。 一個(gè)月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像盆昙,于是被迫代替她去往敵國和親羽历。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容