在做View Controller
的生命周期的時候悲没,由于要用到UINavigationController
狰闪,就干脆繼續(xù)學習了一波這個知識點扎附,參考了這篇文章
一.定義
UINavigationController(導航控制器)
是一個容器控制器第煮,其內部有多個UIViewController(視圖控制器)
的內容杜秸,我們可以通過UINavigationController
的view
屬性獲取到其自身的視圖放仗,在該視圖上面有一個位于界面頂部的UINavigationBar(導航欄)
和位于界面底部的默認隱藏的UIToolbar(工具欄)
,以及一個位于界面中間部分的UIViewController
的view
撬碟。
當用戶在UINavigationController
的層級結構中來回切換的時候诞挨,UINavigationBar
和UIToolbar
的內容會隨之發(fā)生變化,但是其本身并不會發(fā)生變化呢蛤,唯一發(fā)生變化的就是位于界面中間部分的UIViewController
的view
惶傻。
二.UIViewController堆棧的管理
UINavigationController
通過其管理的UIViewController堆棧
來決定展示在UINavigationController
中間部位的內容,該內容由位于UIViewController堆棧
的棧頂位置的UIViewController
決定其障。
下圖的View Controllers
是UIViewController堆棧
银室,navigationBar
是位于頂部的UINavigationBar
,toolBar
是位于底部的UIToolbar
励翼。
根據(jù)棧的定義蜈敢,如果我們要實現(xiàn)這個棧的內容,既可以用push和pop對UIViewController
進行操作汽抚,也可以直接設置UIViewController堆棧
的內容抓狭。
1.push
//push
//方法一
/*
* 參數(shù)一: UIViewController, 該參數(shù)不可以使用UITabBarController的實例
* 參數(shù)二: 是否執(zhí)行動畫
*/
[navigationController pushViewController:[[UIViewController alloc] init] animated:YES];
//方法二
/*
* 參數(shù)一: UIViewController, 該參數(shù)不可以使用UITabBarController的實例
* 參數(shù)二: 要求展示UIViewController的對象
*/
[navigationController showViewController:[[UIViewController alloc] init] sender:nil];
2.pop
//pop一個UIViewController
/*
* 參數(shù)一: 是否執(zhí)行動畫
* 返回值: 從UIViewController堆棧中Pop出來的UIViewController
*/
UIViewController *viewController = [navigationController popViewControllerAnimated:YES];
//一直pop到根視圖控制器
/*
* 參數(shù)一: 是否執(zhí)行動畫
* 返回值: 從UIViewController堆棧中Pop出來的UIViewController數(shù)組
*/
NSArray *viewControllers = [navigationController popToRootViewControllerAnimated:YES];
//一直pop到指定的UIViewController
/*
* 參數(shù)一: 指定UIViewController, 該UIViewController必須位于當前UIViewController堆棧中
* 參數(shù)二: 是否執(zhí)行動畫
* 返回值: 從UIViewController堆棧中Pop出來的UIViewController數(shù)組
*/
NSArray *viewControllers = [navigationController popToViewController:navigationController.viewControllers[0] animated:YES];
3.獲取
// 獲取位于UIViewController堆棧棧頂位置的UIViewController
UIViewController *viewController = navigationController.topViewController;
三.UINavigationBar的管理
UINavigationController
通過位于UIViewController堆棧
棧頂位置的UIViewController
的navigationItem
屬性(該屬性位于UIViewController
的UINavigationControllerItem
類目中)來管理UINavigationBar
展示的內容,同時UINavigationController
也提供了navigationBar
屬性, 允許開發(fā)者通過該屬性設置UINavigationBar
的外觀造烁。
值得注意的是否过,UINavigationController
是UINavigationBar
的delegate, 其負責響應該UINavigationBarDelegate
的代理方法, 并據(jù)此更新位于界面中間部分的UIViewController
的視圖。
1.設置UINavigationBar的外觀
我們可以通過該屬性設置UINavigationBar
的外觀, 但是不要通過該屬性設置其frame, bounds, alpha等屬性, 更不要修改其層級結構膨蛮。
// 屬性
@property(nonatomic, readonly) UINavigationBar *navigationBar;
// 示例
navigationController.navigationBar.barStyle = UIBarStyleDefault;
2.設置UINavigationBar的隱藏狀態(tài)
// 屬性
@property(nonatomic, getter=isNavigationBarHidden) BOOL navigationBarHidden;
// 示例
navigationController.navigationBarHidden = YES;
3.設置UINavigationBar的隱藏狀態(tài)(可選動畫)
// 方法
/*
* 參數(shù)一: 隱藏狀態(tài)
* 參數(shù)二: 是否執(zhí)行動畫
*/
- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated;
// 示例
[navigationController setNavigationBarHidden:YES animated:YES];
四.UIToolbar的管理
UINavigationController
通過位于UIViewController堆棧
棧頂位置的UIViewController
的toolbarItems
屬性(該屬性位于UIViewController
的UINavigationControllerContextualToolbarItems
類目中)來管理UIToolbar
展示的內容叠纹,同時UINavigationController
也提供了toolbar
屬性, 允許開發(fā)者通過該屬性設置UIToolbar
的外觀。
1.設置UIToolbar的外觀
// 屬性
@property(nonatomic, readonly) UIToolbar *toolbar;
// 示例
navigationController.toolbar.barStyle = UIBarStyleDefault;
2.設置UIToolbar的隱藏狀態(tài)
// 屬性
@property(nonatomic, getter=isToolbarHidden) BOOL toolbarHidden;
// 示例
navigationController.toolbarHidden = NO;
3.設置UIToolbar的隱藏狀態(tài)(可選動畫)
// 方法
/*
* 參數(shù)一: 隱藏狀態(tài)
* 參數(shù)二: 是否執(zhí)行動畫
*/
- (void)setToolbarHidden:(BOOL)hidden animated:(BOOL)animated;
// 示例
[navigationController setToolbarHidden:NO animated:YES];
五.手勢識別器的管理
1.獲取手勢識別器
// 側滑返回手勢識別器
@property(nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer;
// 用于輕拍隱藏UINavigationBar與UIToolbar的手勢識別器
@property(nonatomic, readonly, assign) UITapGestureRecognizer *barHideOnTapGestureRecognizer;
// 用于輕掃隱藏UINavigationBar與UIToolbar的手勢識別器
@property(nonatomic, readonly, strong) UIPanGestureRecognizer *barHideOnSwipeGestureRecognizer;
// 示例
UIGestureRecognizer *interactivePopGestureRecognizer = navigationController.interactivePopGestureRecognizer;
2.通過手勢隱藏UINavigationBar與UIToolbar
// 輕拍隱藏敞葛、再次輕拍顯示
@property(nonatomic, readwrite, assign) BOOL hidesBarsOnTap;
// 向上輕掃隱藏誉察、向下輕掃顯示
@property(nonatomic, readwrite, assign) BOOL hidesBarsOnSwipe;
// 橫屏隱藏(此時輕拍顯示)、豎屏顯示
@property(nonatomic, readwrite, assign) BOOL hidesBarsWhenVerticallyCompact;
// 鍵盤出現(xiàn)隱藏惹谐、鍵盤消失保持隱藏(此時輕拍顯示)
@property(nonatomic, readwrite, assign) BOOL hidesBarsWhenKeyboardAppears;
// 示例
navigationController.hidesBarsOnTap = YES;
六.UINavigationController對象的初始化
//通過UIViewController初始化
/*
* 參數(shù)一: UIViewController, 該參數(shù)不可以使用UITabBarController的實例
*/
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[UIViewController alloc] init]];
//通過UINavigationBar持偏、UIToolbar初始化
/*
* 參數(shù)一: 自定義UINavigationBar的子類, 如果是nil則為UINavigationBar類
* 參數(shù)二: 自定義UIToolbar的子類, 如果是nil則為UIToolbar類
*/
UINavigationController *navigationController = [[UINavigationController alloc] initWithNavigationBarClass:[UINavigationBar class] toolbarClass:[UIToolbar class]];
七. UINavigationBar
1.概述
UINavigationBar
是一個在層級結構中起導航作用的視覺控件, 其一般展示形式如下圖所示
2.UINavigationItem堆棧的管理
UINavigationBar
雖然繼承自UIView
, 但是其并非通過addSubview:
方法來添加子視圖, 而是通過其管理的UINavigationItem堆棧
來決定展示在UINavigationBar
中的內容。
如下圖所示氨肌,其中:
items
是UINavigationItem堆棧
;
topItem
是位于UINavigationItem堆棧
棧頂位置的UINavigationItem
;
backItem
是位于UINavigationItem堆棧
棧頂下方位置的UINavigationItem
鸿秆。
我們可以利用系統(tǒng)提供的方法向UINavigationItem堆棧
中Push一個UINavigationItem
, 從UINavigationItem堆棧
中Pop一個UINavigationItem
, 也可以直接設置UINavigationItem堆棧
中的全部UINavigationItem
。
3. UINavigationBar的內容
UINavigationBar
通過UINavigationItem堆棧
按照如下方式來決定展示在UINavigationBa
r中的內容
位于中間的標題會根據(jù)下方順序選擇展示的內容:
如果topItem設置了標題視圖(titleView屬性), 則展示標題視圖
如果topItem設置了標題文字(title屬性), 則展示標題文字
如果以上都未設置, 則展示空白
位于右側的按鈕會根據(jù)下方順序選擇展示的內容:
如果topItem設置了右側按鈕(rightBarButtonItem屬性), 則展示右側按鈕
如果以上都未設置, 則展示空白
位于左側的按鈕會根據(jù)下方順序選擇展示的內容:
如果topItem設置了左側按鈕(leftBarButtonItem屬性), 則展示左側按鈕
如果backItem設置了返回按鈕(backBarButtonItem屬性), 則展示返回按鈕
如果backItem設置了標題文字(title屬性), 則展示利用標題文字封裝的返回按鈕
如果以上都未設置, 則展示利用文字"Back"封裝的返回按鈕(前提是
UINavigationItem堆棧
中有超過一個的UINavigationItem
)
// 初始化UINavigationItem對象
/*
* 參數(shù)一: 標題文字
*/
- (instancetype)initWithTitle:(NSString *)title;
// 示例
UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"Owen"];
//設置標題文字
// 屬性
@property(nonatomic, copy) NSString *title;
// 示例
navigationItem.title = @"Title";
//設置標題視圖
// 屬性
@property(nonatomic, strong) UIView *titleView;
// 示例
navigationItem.titleView = [UIButton buttonWithType:UIButtonTypeInfoLight];
//設置提示文字
// 屬性
@property(nonatomic, copy) NSString *prompt;
// 示例
navigationItem.title = @"Prompt";
//設置返回按鈕
// 屬性
@property(nonatomic, strong) UIBarButtonItem *backBarButtonItem;
// 示例
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Owen" style:UIBarButtonItemStylePlain target:nil action:nil];
navigationItem.backBarButtonItem = barButtonItem;
4.UINavigationBar的外觀
UINavigationBar
類中提供了大量屬性/方法用于設置其外觀, 我們可以設置其樣式怎囚、背景顏色卿叽、色彩顏色桥胞、文字屬性等
同樣, 我們也可以設置其背景圖片、陰影圖片等
//設置樣式
//該屬性默認為UIBarStyleDefault(白底黑字), 可選項為UIBarStyleBlack(黑底白字)
navigationBar.barStyle = UIBarStyleDefault;
//設置透明性
navigationBar.translucent = YES;
//設置背景顏色
navigationBar.barTintColor = [UIColor orangeColor];
//設置色彩顏色
navigationBar.tintColor = [UIColor greenColor];
//設置標題文字屬性
navigationBar.titleTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:30], NSForegroundColorAttributeName: [UIColor whiteColor]};
//設置/獲取背景圖片
/*
* 參數(shù)一: 背景圖片
* 參數(shù)二: 默認為UIBarPositionAny(不指定), 可選項為UIBarPositionBottom(在容器下方), UIBarPositionTop(在容器上方), UIBarPositionTopAttached(在屏幕上方, 與容器平級)
* 參數(shù)三: 可選項為UIBarMetricsDefault(豎屏, 橫屏未設置也使用該效果), UIBarMetricsCompact(橫屏), UIBarMetricsDefaultPrompt(擁有提示文字的豎屏, 橫屏未設置也使用該效果), UIBarMetricsCompactPrompt(擁有提示文字的橫屏)
*/
[navigationBar setBackgroundImage:[UIImage imageNamed:@""] forBarPosition:UIBarPositionTop barMetrics:UIBarMetricsDefault];
//設置陰影圖片
navigationBar.shadowImage = [UIImage imageNamed:@""];
//設置返回按鈕圖片(需要同時設置)
navigationBar.backIndicatorImage = [UIImage imageNamed:@""];
navigationBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:@""];