2018-07-11 UINavigationController和UINavigationBar

在做View Controller的生命周期的時候悲没,由于要用到UINavigationController狰闪,就干脆繼續(xù)學習了一波這個知識點扎附,參考了這篇文章

一.定義

UINavigationController(導航控制器)是一個容器控制器第煮,其內部有多個UIViewController(視圖控制器)的內容杜秸,我們可以通過UINavigationControllerview屬性獲取到其自身的視圖放仗,在該視圖上面有一個位于界面頂部的UINavigationBar(導航欄)和位于界面底部的默認隱藏的UIToolbar(工具欄),以及一個位于界面中間部分的UIViewControllerview撬碟。

UINavigationController層級結構

當用戶在UINavigationController的層級結構中來回切換的時候诞挨,UINavigationBarUIToolbar的內容會隨之發(fā)生變化,但是其本身并不會發(fā)生變化呢蛤,唯一發(fā)生變化的就是位于界面中間部分的UIViewControllerview惶傻。

二.UIViewController堆棧的管理

UINavigationController通過其管理的UIViewController堆棧來決定展示在UINavigationController中間部位的內容,該內容由位于UIViewController堆棧的棧頂位置的UIViewController決定其障。

下圖的View ControllersUIViewController堆棧银室,navigationBar是位于頂部的UINavigationBartoolBar是位于底部的UIToolbar励翼。

UIViewController堆棧

根據(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堆棧棧頂位置的UIViewControllernavigationItem屬性(該屬性位于UIViewControllerUINavigationControllerItem類目中)來管理UINavigationBar展示的內容,同時UINavigationController也提供了navigationBar屬性, 允許開發(fā)者通過該屬性設置UINavigationBar的外觀造烁。

值得注意的是否过,UINavigationControllerUINavigationBardelegate, 其負責響應該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堆棧棧頂位置的UIViewControllertoolbarItems屬性(該屬性位于UIViewControllerUINavigationControllerContextualToolbarItems類目中)來管理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中的內容。

如下圖所示氨肌,其中:
itemsUINavigationItem堆棧;
topItem是位于UINavigationItem堆棧棧頂位置的UINavigationItem;
backItem是位于UINavigationItem堆棧棧頂下方位置的UINavigationItem鸿秆。

我們可以利用系統(tǒng)提供的方法向UINavigationItem堆棧中Push一個UINavigationItem, 從UINavigationItem堆棧中Pop一個UINavigationItem, 也可以直接設置UINavigationItem堆棧中的全部UINavigationItem

3. UINavigationBar的內容

UINavigationBar通過UINavigationItem堆棧按照如下方式來決定展示在UINavigationBar中的內容

位于中間的標題會根據(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:@""];
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末考婴,一起剝皮案震驚了整個濱河市贩虾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沥阱,老刑警劉巖缎罢,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異考杉,居然都是意外死亡策精,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門崇棠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咽袜,“玉大人,你說我怎么就攤上這事枕稀〕晏#” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵抽莱,是天一觀的道長。 經常有香客問我骄恶,道長食铐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任芍碧,我火速辦了婚禮鼎姐,結果婚禮上去团,老公的妹妹穿的比我還像新娘。我一直安慰自己斟叼,他們只是感情好,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布春寿。 她就那樣靜靜地躺著朗涩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绑改。 梳的紋絲不亂的頭發(fā)上谢床,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天,我揣著相機與錄音厘线,去河邊找鬼识腿。 笑死,一個胖子當著我的面吹牛造壮,可吹牛的內容都是我干的渡讼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼成箫!你這毒婦竟也來了展箱?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤伟众,失蹤者是張志新(化名)和其女友劉穎析藕,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凳厢,經...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡账胧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了先紫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片治泥。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖遮精,靈堂內的尸體忽然破棺而出居夹,到底是詐尸還是另有隱情,我是刑警寧澤本冲,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布准脂,位于F島的核電站,受9級特大地震影響檬洞,放射性物質發(fā)生泄漏狸膏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一添怔、第九天 我趴在偏房一處隱蔽的房頂上張望湾戳。 院中可真熱鬧,春花似錦广料、人聲如沸砾脑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽韧衣。三九已至,卻和暖如春购桑,著一層夾襖步出監(jiān)牢的瞬間汹族,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工其兴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留顶瞒,地道東北人。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓元旬,卻偏偏與公主長得像榴徐,于是被迫代替她去往敵國和親守问。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內容