UINavigationController這一篇就夠了
(一)UINavigationController及其相關控件之間的關系
@interface UINavigationController : UIViewController
@property(nonatomic,readonly) UINavigationBar *navigationBar;
@interface UIViewController (UINavigationControllerItem)
@property(nonatomic,readonly,strong) UINavigationItem *navigationItem;
@interface UINavigationBar : UIView
@property(nullable, nonatomic,readonly,strong) UINavigationItem topItem;
@property(nullable, nonatomic,readonly,strong) UINavigationItem backItem;
@property(nullable,nonatomic,copy) NSArray<UINavigationItem > items;
@interface UINavigationItem : NSObject
@property(nullable,nonatomic,strong) UIBarButtonItem backBarButtonItem
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem > leftBarButtonItems;
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem > rightBarButtonItems;
@property(nullable, nonatomic,strong) UIBarButtonItem leftBarButtonItem;
@property(nullable, nonatomic,strong) UIBarButtonItem *rightBarButtonItem;
@interface UIBarButtonItem : UIBarItem
@property(nullable, nonatomic) SEL action;
@interface UIBarItem : NSObject
@property(nullable, nonatomic,copy) NSString title;
@property(nullable, nonatomic,strong) UIImage image;</code></pre>
通過對上述幾個類的屬性的羅列,我們可以做個總結
基本介紹
- UIBarItem
一個可以放置在Bar之上的所有小控件類的抽象類,可以設置標題,圖片等
- UIBarButtonItem
繼承UIBarItem,增加了動作以及目標等button的屬性。相當于放在UIToolBar或者UINavigationBar上的特殊的button。
- UINavigationItem
包含了title,prompt,titleView,leftBarButtonItem,rightBarButtonItem,backBarButonItem等當前頁面上所有的信息
- UINavigationBar
NavigaitonBar就是導航欄 主要對UINavigationItem進行棧管理 展示導航欄的外觀背景
- UINavigationController
包含了viewcontrollers、navigationbar、toolbar
關系綜述
- UINavigationController是一個容器類,對ViewController進行棧管理,包含navigationBar。
- UINavigationBar 即UINavigationController頂部的導航欄,主要負責外觀背景的展示,并對navigationItem進行棧管理
- UINavigationItem是導航欄上顯示的具體的元素的一個抽象類,UINavigationController 通過Category的方法為ViewController添加了一個navigationItem,把UINavigationItem交由ViewController管理
// Created on-demand so that a view controller may customize its navigation appearance.
這里引用 葉落寒 的一段介紹,更加的通俗易懂
通俗地說就是,UINavigationController是個容器,里面可以裝很多UIViewController。裝這么多UIViewController讓用戶怎么控制它們呢?總得有個工具吧,這個工具就是UINavigationBar。一個容器就這么一個bar,相當于控制臺吧。但是管理那么多UIViewController,控制臺上得按鈕啊、標題啊,都千篇一律是不是看起來太無聊了。為了解決這個問題,UINavigationController為每個UIViewController生成一個UINavigationItem,通過這個UINavigationItem可以改變控制臺“上面”的按鈕和標題。如果你不自定義UINavigationItem,UINavigationController會使用默認的;
(二)UINavigationController及其相關控件的屬性和方法
1. UIBarButtonItem
//初始化方法
- (instancetype)init;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;
- (instancetype)initWithImage:(nullable UIImage )image landscapeImagePhone:(nullable UIImage )landscapeImagePhone style:(UIBarButtonItemStyle)style target:(nullable id)target action:(nullable SEL)action;
- (instancetype)initWithTitle:(nullable NSString *)title style:(UIBarButtonItemStyle)style target:(nullable id)target action:(nullable SEL)action;
- (instancetype)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(nullable id)target action:(nullable SEL)action;
- (instancetype)initWithCustomView:(UIView *)customView;
@property(nonatomic) UIBarButtonItemStyle style; //類型
@property(nonatomic) CGFloat width;
@property(nullable, nonatomic,copy) NSSet<NSString > possibleTitles;
@property(nullable, nonatomic,strong) __kindof UIView customView;
@property(nullable, nonatomic) SEL action;
@property(nullable, nonatomic,weak) id target;
@property(nullable, nonatomic,strong) UIColor tintColor
//為任意style的button設置背景圖片
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
- (nullable UIImage *)backgroundImageForState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
//為特定style的button設置背景圖片
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state style:(UIBarButtonItemStyle)style barMetrics:(UIBarMetrics)barMetrics
- (nullable UIImage *)backgroundImageForState:(UIControlState)state style:(UIBarButtonItemStyle)style barMetrics:(UIBarMetrics)barMetrics
//設置背景圖片垂直方向的偏移量
- (void)setBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics
- (CGFloat)backgroundVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics
//設置標題的偏移量
- (void)setTitlePositionAdjustment:(UIOffset)adjustment forBarMetrics:(UIBarMetrics)barMetrics
- (nullable UIImage *)backButtonBackgroundImageForState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
//設置返回按鈕標題偏移量
- (void)setBackButtonTitlePositionAdjustment:(UIOffset)adjustment forBarMetrics:(UIBarMetrics)barMetrics
- (UIOffset)backButtonTitlePositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics
//設置返回按鈕背景圖片在垂直方向上的偏移量
- (void)setBackButtonBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics
- (CGFloat)backButtonBackgroundVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics</code></pre>
typedef NS_ENUM(NSInteger, UIBarButtonSystemItem) {
UIBarButtonSystemItemDone,//顯示完成
UIBarButtonSystemItemCancel,//顯示取消
UIBarButtonSystemItemEdit, //顯示編輯
UIBarButtonSystemItemSave, //顯示保存
UIBarButtonSystemItemAdd,//顯示加號
UIBarButtonSystemItemFlexibleSpace,//什么都不顯示,占位一個空間位置
UIBarButtonSystemItemFixedSpace,//和上一個類似
UIBarButtonSystemItemCompose,//顯示寫入按鈕
UIBarButtonSystemItemReply,//顯示循環按鈕
UIBarButtonSystemItemAction,//顯示活動按鈕
UIBarButtonSystemItemOrganize,//顯示組合按鈕
UIBarButtonSystemItemBookmarks,//顯示圖書按鈕
UIBarButtonSystemItemSearch,//顯示查找按鈕
UIBarButtonSystemItemRefresh,//顯示刷新按鈕
UIBarButtonSystemItemStop,//顯示停止按鈕
UIBarButtonSystemItemCamera,//顯示相機按鈕
UIBarButtonSystemItemTrash,//顯示移除按鈕
UIBarButtonSystemItemPlay,//顯示播放按鈕
UIBarButtonSystemItemPause,//顯示暫停按鈕
UIBarButtonSystemItemRewind,//顯示退后按鈕
UIBarButtonSystemItemFastForward,//顯示前進按鈕
UIBarButtonSystemItemUndo,//顯示消除按鈕
UIBarButtonSystemItemRedo ,//顯示重做按鈕
UIBarButtonSystemItemPageCurl ,//在tool上有效
};
2.UINavigationItem
NS_CLASS_AVAILABLE_IOS(2_0) @interface UINavigationItem : NSObject <NSCoding>
//初始化
- (instancetype)initWithTitle:(NSString *)title NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
//設置導航欄中間的內容標題
@property(nullable, nonatomic,copy) NSString title;
//設置導航欄中間的內容視圖
@property(nullable, nonatomic,strong) UIView titleView;
//提示
@property(nullable,nonatomic,copy) NSString prompt;
//返回
@property(nullable,nonatomic,strong) UIBarButtonItem backBarButtonItem;
//是否隱藏返回Button
@property(nonatomic,assign) BOOL hidesBackButton;
- (void)setHidesBackButton:(BOOL)hidesBackButton animated:(BOOL)animated;
//左邊數組Item
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem > leftBarButtonItems NS_AVAILABLE_IOS(5_0);
//右邊數組Item
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem > rightBarButtonItems NS_AVAILABLE_IOS(5_0);
- (void)setLeftBarButtonItems:(nullable NSArray<UIBarButtonItem > )items animated:(BOOL)animated NS_AVAILABLE_IOS(5_0);
- (void)setRightBarButtonItems:(nullable NSArray<UIBarButtonItem > )items animated:(BOOL)animated NS_AVAILABLE_IOS(5_0);
//通過指定該屬性為YES,可以讓leftBarButtonItem和backBarButtonItem同時顯示,其中leftBarButtonItem顯示在backBarButtonItem的右邊 默認值為NO
@property(nonatomic) BOOL leftItemsSupplementBackButton NS_AVAILABLE_IOS(5_0);
//左邊Item
@property(nullable, nonatomic,strong) UIBarButtonItem leftBarButtonItem;
//右邊Item
@property(nullable, nonatomic,strong) UIBarButtonItem rightBarButtonItem;
- (void)setLeftBarButtonItem:(nullable UIBarButtonItem *)item animated:(BOOL)animated;
- (void)setRightBarButtonItem:(nullable UIBarButtonItem *)item animated:(BOOL)animated;
@end</code></pre>
prompt 是一個NSString類型描述,注意添加該描述以后NavigationBar的高度會增加30,總的高度會變成74(不管當前方向是Portrait還是Landscape,此模式下navgationbar都使用高度44加上prompt30的方式進行顯示)。
如:
self.navigationItem.prompt=@"這是什么?";
self.title=@"HAH";

prompt.png
3.UINavigationBar
NS_CLASS_AVAILABLE_IOS(2_0) @interface UINavigationBar : UIView <NSCoding, UIBarPositioning>
//UIBarStyleDefault 灰色背景 白色文字 UIBarStyleBlack 純黑色背景 白色文字
@property(nonatomic,assign) UIBarStyle barStyle;
@property(nullable,nonatomic,weak) id<UINavigationBarDelegate> delegate;
//Translucent設置成透明度,設置成YES會有一種模糊效果
@property(nonatomic,assign,getter=isTranslucent) BOOL translucent NS_AVAILABLE_IOS(3_0) UI_APPEARANCE_SELECTOR;
//UINavigationBar上面不只是簡單的顯示標題,它也將標題進行了堆棧的管理,每一個標題抽象為的對象在iOS系統中是UINavigationItem對象,我們可以通過push與pop操作管理item組。
//向棧中添加一個item,上一個item會被推向導航欄的左側,變為pop按鈕,會有一個動畫效果
- (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated;
//pop一個item
- (nullable UINavigationItem )popNavigationItemAnimated:(BOOL)animated;
//當前push到最上層的item
@property(nullable, nonatomic,readonly,strong) UINavigationItem topItem;
//僅次于最上層的item,一般式被推向導航欄左側的item
@property(nullable, nonatomic,readonly,strong) UINavigationItem backItem;
//獲取堆棧中所有item的數組
@property(nullable,nonatomic,copy) NSArray<UINavigationItem > *items;
//設置一組item
- (void)setItems:(nullable NSArray<UINavigationItem > )items animated:(BOOL)animated;
//系統類型按鈕文字顏色
@property(null_resettable, nonatomic,strong) UIColor *tintColor;
//通過barTintColor來設置背景色
@property(nullable, nonatomic,strong) UIColor *barTintColor NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
//設置工具欄背景和陰影圖案
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
- (nullable UIImage *)backgroundImageForBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
//通過背景圖片來設置導航欄的外觀
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (nullable UIImage *)backgroundImageForBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
//背景陰影圖片 - 即分割線
@property(nullable, nonatomic,strong) UIImage *shadowImage NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR;
//標題的富文本
@property(nullable,nonatomic,copy) NSDictionary<NSString ,id> titleTextAttributes NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
//標題垂直偏移
- (void)setTitleVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (CGFloat)titleVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
//設置返回按鈕的圖片
@property(nullable,nonatomic,strong) UIImage backIndicatorImage NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
@property(nullable,nonatomic,strong) UIImage backIndicatorTransitionMaskImage NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
@end</code></pre>
4.UINavigationController
NS_CLASS_AVAILABLE_IOS(2_0) @interface UINavigationController : UIViewController
//UINavigationController初始化,自定義NavigationBar,自定義toolbar
- (instancetype)initWithNavigationBarClass:(nullable Class)navigationBarClass toolbarClass:(nullable Class)toolbarClass NS_AVAILABLE_IOS(5_0);
//UINavigationController初始化,導航控制器的根控制器
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController;
//壓棧:將目標控制器壓入棧中
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
//彈棧:將棧頂控制器從棧中彈出
- (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated;
//彈棧:彈到指定的目標控制器
- (nullable NSArray<__kindof UIViewController > )popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
//彈棧:彈到根控制器
- (nullable NSArray<__kindof UIViewController > )popToRootViewControllerAnimated:(BOOL)animated;
//導航棧的棧頂視圖 只讀 就是某個導航棧的棧頂視圖,和導航息息相關
@property(nullable, nonatomic,readonly,strong) UIViewController topViewController;
//當前顯示的控制器 只讀 visibleViewController和哪個導航棧沒有關系,只是當前顯示的控制器,也就是說任意一個導航的visibleViewController所返回的值應該是一樣的
@property(nullable, nonatomic,readonly,strong) UIViewController visibleViewController;
//棧里的視圖控制器數組
@property(nonatomic,copy) NSArray<__kindof UIViewController > viewControllers;
//替換棧中的視圖控制器數組
- (void)setViewControllers:(NSArray<UIViewController > )viewControllers animated:(BOOL)animated NS_AVAILABLE_IOS(3_0);
//是否隱藏導航欄
@property(nonatomic,getter=isNavigationBarHidden) BOOL navigationBarHidden;
//設置導航欄隱藏 是否有動畫
- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated;
//導航欄
@property(nonatomic,readonly) UINavigationBar *navigationBar;
//toolbar是否隱藏
@property(nonatomic,getter=isToolbarHidden) BOOL toolbarHidden NS_AVAILABLE_IOS(3_0);
//toolbar是否隱藏 是否有動畫
- (void)setToolbarHidden:(BOOL)hidden animated:(BOOL)animated NS_AVAILABLE_IOS(3_0);
//toolbar對象
@property(null_resettable,nonatomic,readonly) UIToolbar *toolbar NS_AVAILABLE_IOS(3_0);
//委托
@property(nullable, nonatomic, weak) id<UINavigationControllerDelegate> delegate;
//邊緣側滑返回手勢
@property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0);
//展示視圖控制器
- (void)showViewController:(UIViewController *)vc sender:(nullable id)sender NS_AVAILABLE_IOS(8_0); // Interpreted as pushViewController:animated:
//輸入鍵盤出現時將導航欄隱藏 IOS8特性
@property (nonatomic, readwrite, assign) BOOL hidesBarsWhenKeyboardAppears NS_AVAILABLE_IOS(8_0);
//滾動頁面時隱藏Bar IOS8特性
@property (nonatomic, readwrite, assign) BOOL hidesBarsOnSwipe NS_AVAILABLE_IOS(8_0);
//獲取能夠隱藏navigationBar的滑動手勢 只讀
@property (nonatomic, readonly, strong) UIPanGestureRecognizer *barHideOnSwipeGestureRecognizer NS_AVAILABLE_IOS(8_0);
//當設置為true時,橫向方向時隱藏NavigationBar
@property (nonatomic, readwrite, assign) BOOL hidesBarsWhenVerticallyCompact NS_AVAILABLE_IOS(8_0);
//當設置為true時,如果有沒處理的點擊手勢就會隱藏和現實navigationBar
@property (nonatomic, readwrite, assign) BOOL hidesBarsOnTap NS_AVAILABLE_IOS(8_0);
//獲取能夠隱藏navigationBar的點擊手勢 只讀
@property (nonatomic, readonly, assign) UITapGestureRecognizer *barHideOnTapGestureRecognizer NS_AVAILABLE_IOS(8_0);
@end</code></pre>
@interface UIViewController (UINavigationControllerItem)
//導航欄上面用戶自定義視圖
@property(nonatomic,readonly,strong) UINavigationItem *navigationItem;
//推送時隱藏bottom
@property(nonatomic) BOOL hidesBottomBarWhenPushed;
//下級視圖的導航控制器
@property(nullable, nonatomic,readonly,strong) UINavigationController *navigationController;
@end
@interface UIViewController (UINavigationControllerContextualToolbarItems)
//屬性設置工具條中包含的按鈕
@property (nullable, nonatomic, strong) NSArray<__kindof UIBarButtonItem > toolbarItems NS_AVAILABLE_IOS(3_0);
(void)setToolbarItems:(nullable NSArray<UIBarButtonItem > )toolbarItems animated:(BOOL)animated NS_AVAILABLE_IOS(3_0);
@end</code></pre>
(三)實際開發過程中的一些問題
1.UINavigationBar的背景顏色
-(void)changeNavigationBarBackgroundColor {
//背景色
self.navigationBar.barTintColor = [UIColor blueColor];
//title字體
//[self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor lightGrayColor],NSFontAttributeName:[UIFont systemFontOfSize:17]}];
//修改UIBarButtonItem 圖片 title顏色
self.navigationBar.tintColor = [UIColor greenColor];
//是否半透明 當為YES時 設置的導航欄背景顏色會和實際rgb值有誤差
self.navigationBar.translucent = NO;
//如果想要半透明效果 顏色沒有色差 可以通過設置背景圖片的方法 背景圖片會覆蓋barTintColor
//- (void)setBackgroundImage:(nullable UIImage )backgroundImage forBarMetrics:(UIBarMetrics)barMetrics
}</code></pre>
2.UINavigationBar底部的shadowImage
Apple官方對shadowImage有這樣的介紹:
/ Default is nil. When non-nil, a custom shadow image to show instead of the default shadow image. For a custom shadow to be shown, a custom background image must also be set with -setBackgroundImage:forBarMetrics: (if the default background image is used, the default shadow image will be used). /
設置shadowImage必須先setBackgroundImage,否則無法實現效果
-(void)changeNavigationBarBottonLine {
//設置底部line顏色時需要同時設置backgroundImage即導航欄的背景圖片 否則沒有效果
[self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self.navigationBar setShadowImage:[self imageWithColor:[UIColor redColor]]];
//此處設置透明顏色的image,底部line即可隱藏,但此種方法隱藏,沒有辦法再顯示 下面方法通過找到該view 控制其hidden屬性
//[self reducibilityHiddenNavogationBarLine];
}
找到該imageView設置起Hidden為YES
-(void)reducibilityHiddenNavogationBarLine {
UIImageView
imageView = [self findLineImageViewUnder:self.navigationBar];
if (imageView) {
imageView.hidden = YES;
}
}</code></pre>
找到該imageView
-(UIImageView )findLineImageViewUnder:(UIView )view {
if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height <= 1.0) {
return (UIImageView *)view;
}
for (UIView * subView in view.subviews) {
UIImageView * imageView = [self findLineImageViewUnder:subView];
if (imageView) {
return imageView;
}
}
return nil;
}</code></pre>
3.自定義導航欄的返回按鈕
@property(nonatomic,readonly) UINavigationBar *navigationBar;// The navigation bar managed by the controller. Pushing, popping or setting navigation items on a managed navigation bar is not supported.
受controller管理的navigationBar 不支持對navigation items操作,所以此處對返回按鈕的操作是在ViewController完成的,以下代碼中self表示ViewController
Apple官方對setBackIndicatorImage和setBackIndicatorTransitionMaskImage做了如下解釋,必須同時設置才能生效
/*
The back indicator image is shown beside the back button.
The back indicator transition mask image is used as a mask for content during push and pop transitions
Note: These properties must both be set if you want to customize the back indicator image.
*/
1.自定義文字+圖片
-(void)createCustomBackBarItem {
//修改圖片文字顏色
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
//替換圖片
[self.navigationController.navigationBar setBackIndicatorImage:[UIImage imageNamed:@"erwema"]];
[self.navigationController.navigationBar setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"erwema"]];
//設置文字
UIBarButtonItem backBarItem = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backBarItem;
}</code></pre>
注意:
對backBarButtonItem的修改是在當前viewController前一個頁面完成的,在當前頁面修改針對下一個viewController的navigationItem生效
2.不顯示文字
設置Title在Y方向上的偏移量,使其移除屏幕,該方法在第一次進入時會有個文字移動的動畫效果,效果不好,不推薦使用
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -100) forBarMetrics:UIBarMetricsDefault];
3.使用leftBarButtonItem替代backBarButtonItem
使用這種方法,不能使用邊緣滑動返回手勢,且不能同時設置圖片和標題
-(void)setLeftBarItemBack
{
UIBarButtonItem
leftBarBtnItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"back"] style:UIBarButtonItemStylePlain target:self action:@selector(clickLeftBarBtnItem:)];
[self.navigationItem setLeftBarButtonItem:leftBarBtnItem animated:YES];
self.navigationItem.leftBarButtonItem.tintColor = NavigationLeftBackColor;
}
/**
- 導航條leftBarBtn事件
*/
- (void)clickLeftBarBtnItem:(UIBarButtonItem )sender {
[self.navigationController popViewControllerAnimated:YES];
}</code></pre>
4.使用CustomView的方法
此方法不適于backBarButtonItem,只能用于leftBarButtonItem
注意:
1.如果B視圖有一個自定義的左側按鈕(leftBarButtonItem),則會顯示這個自定義按鈕;
2.如果B沒有自定義按鈕,但是A視圖的backBarButtonItem屬性有自定義項,則顯示這個自定義項;
3.如果前2條都沒有,則默認顯示一個后退按鈕,后退按鈕的標題是A視圖的標題;
此處注意:
5.0中新增加了一個屬性leftItemsSupplementBackButton,通過指定該屬性為YES,可以讓leftBarButtonItem和backBarButtonItem同時顯示,其中leftBarButtonItem顯示在backBarButtonItem的右邊。
使用3、4方法,邊緣返回會失效,此時加上這句代碼依然可以實現邊緣滑動返回
self.navigationController.interactivePopGestureRecognizer.delegate = self;
這里推薦使用 FDFullscreenPopGesture 全屏滑動手勢返回,減少工作量。
4.navigationBar偶爾顯示上一個頁面的navigationBar
一般情況下都是正常的。但是在偶然情況下,會出現在進入新界面后,新界面的navigationBar會突然消失,出現的還是上一個界面的 navigationBar。從此以后,navigationBar 全亂了, kill 掉重新進,恢復正常。
原因:
一般我們會打點調用navigationBarHidden的屬性來設置導航欄是否隱藏,這種方法是不帶動畫效果的。這樣偶爾就會導致錯亂,這應該是一個系統的bug,所以應盡量使用
[self.navigationController setNavigationBarHidden:YES animated:YES];
來設置navigationBar的Hidden屬性。
5.修改系統navigationBar的高度
UINavigationBar
navigatioBar = self.navigationController.navigationBar;
CGFloat navBarHeight = 100.f;
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, navBarHeight);
[navigatioBar setFrame:frame];</code></pre>
此種方法經測試只有在非rootViewController中才能生效,這樣在第一次進入根視圖的時候navigationBar并不會變高,不知有沒有人知道該如何解決,歡迎賜教。
6.易混淆知識點
1.self.title、self.navigationItem.title、self.tabBarItem.title之間的關系
一目了然
self.navigationItem.title = @"my title"; //sets navigation bar title.
self.tabBarItem.title = @"my title"; //sets tab bar title.
self.title = @"my title"; //sets both of these.
- 如果當前VC通過 self.navigationItem.titleView指定了自定義的titleView,系統將會顯示指定的titleView,設置self.title、self.navigationItem.title不會改變導航欄的標題。
- 如果當前VC沒有指定titleView,系統則會根據當前VC的title或者當前VC的navigationItem.title的內容創建一個UILabel并顯示。
- self.title會重寫navigationItem和tabBarItem的title。
2.self.navigationItem,self.navigationController.navigationItem的關系
navigationItem是UIViewController的一個屬性,navigationController繼承UIViewController,自然會繼承viewControoler的navigationItem屬性。此處self.navigationController.navigationItem是應該被忽視的。navigationItem直接由viewController管理。
3.UIBarMetrics和UIBarPosition
typedef NS_ENUM(NSInteger, UIBarMetrics) {
UIBarMetricsDefault, //橫屏
UIBarMetricsCompact,//豎屏
UIBarMetricsDefaultPrompt = 101, //橫屏且設置了prompt屬性 Applicable only in bars with the prompt property, such as UINavigationBar and UISearchBar
UIBarMetricsCompactPrompt, //豎屏且設置了prompt屬性
};
typedef NS_ENUM(NSInteger, UIBarPosition) {
UIBarPositionAny = 0, //Bar在任何位置
UIBarPositionBottom = 1, //Bar在底部
UIBarPositionTop = 2, //Bar在頂部
UIBarPositionTopAttached = 3, //Bar在頂部,且他的背景擴展到statusBar的區域
} NS_ENUM_AVAILABLE_IOS(7_0);</code></pre>
不正之處,還望多多指教!
參考文章
UINavigationItem UINavigationBar 關系分析
來自:http://www.jianshu.com/p/69b4e7bed7d4