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.
通常情況下我們使用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)航欄。