iOS-UINavigationController官方文檔分析大總結(jié)

一蹋凝、概述

  • 類繼承關(guān)系如下:UINavigationController
    <- UIViewcontroller <- UIResponder <- NSObject
    .
  • 它是一個(gè)容器類視圖控制器,以棧的形式管理一組視圖控制器暴氏,位于棧底的視圖是其rootViewController,管理視圖控制器個(gè)數(shù)理論上不受限制(實(shí)際受內(nèi)存限制)史飞,push和pop方法來彈入彈出控制器诅愚,最多只能顯示一個(gè)視圖控制器缆毁,那就是處于棧頂?shù)囊晥D控制器.
  • 如果不給它添加視圖控制器也不會(huì)報(bào)錯(cuò),界面上也有視圖坪郭,因?yàn)閁INavigationController繼承自UIViewController吭产,也有自己的view侣监,只不過默認(rèn)情況下.view.backgroundColor為nil,即透明的臣淤。
  • 若不給除根視圖控制器之外的其他視圖控制器設(shè)置返回按鈕,UINavigationController會(huì)給他們?cè)O(shè)置返回按鈕(<返回).
  • UINavigationController管理的對(duì)象有:UINavigationBar,UIToolBar.UIToolBar默認(rèn)是隱藏的.
  • UINavigationController允許開發(fā)者自定義UINavigationBar外觀相關(guān)的屬性,但是其frame bounds alpha不允許直接自定義,除非使用UINavigationBar的子類,
    初始化UINavigationController時(shí),方法為:
    initWithNavigationBarClass:toolbarClass:
  • 自定義UINavigationBar,可使用 UIAppearance,該API是全局修改,常在APPDelegate方法里面使用,比如全局設(shè)置標(biāo)題的字體大小 顏色等.

二橄霉、常用函數(shù)

初始化函數(shù):

- initWithRootViewController:

- initWithNavigationBarClass:toolbarClass:

跟導(dǎo)航欄相關(guān)的函數(shù)和屬性

使用push方法能將某個(gè)控制器壓入棧

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;

使用setViewControllers一次壓入多個(gè)控制器vc1->vc2->vc3,會(huì)顯示最后的控制器vc3(處于棧頂)邑蒋,代碼如下:

UINavigationController *nav = [[UINavigationController alloc] init];
window.rootViewController = nav;// 創(chuàng)建3個(gè)測(cè)試控制器UIViewController *vc1 = [[UIViewController alloc] init];
vc1.view.backgroundColor = [UIColor blueColor];
UIViewController *vc2 = [[UIViewController alloc] init];
vc2.view.backgroundColor = [UIColor redColor];
UIViewController *vc3 = [[UIViewController alloc] init];
vc3.view.backgroundColor = [UIColor greenColor];// 最終會(huì)顯示vc3[nav setViewControllers:@[vc1,vc2,vc3] animated:YES];

使用pop方法可以移除棧頂控制器當(dāng)一個(gè)控制器被pop后姓蜂,控制器內(nèi)存就被釋放了(會(huì)調(diào)用deinit/dealloc函數(shù)):

- (UIViewController *)popViewControllerAnimated:(BOOL)animated;

一層一層的返回不方便按厘,可以直接回到指定的控制器VC_A(處與VC_A與棧頂之間的控制器全被釋放),下面代碼執(zhí)行后,VC_A處于棧頂:

- (NSArray *)popToViewController:VC_A animated:(BOOL)animated;

回到根控制器(棧底控制器):

-(NSArray *)popToRootViewControllerAnimated:(BOOL)animated;

獲取被管理的控制器

/// 當(dāng)前管理的所有的控制器
@property(nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers;/// 棧頂控制器
@property(nullable, nonatomic,readonly,strong) UIViewController *topViewController;
/// 當(dāng)前可見的VC钱慢,可能是topViewController逮京,也可能是當(dāng)前topViewController present(modal)出來的VC,總而言之就是可見的VC
@property(nullable, nonatomic,readonly,strong) UIViewController *visibleViewController;

注意束莫,topViewController與visibleViewController大部分情況一樣懒棉,也有可能不同

NavigationBar不常用屬性卻非常有用的屬性

interactivePopGestureRecognizer

關(guān)于這個(gè)屬性的小結(jié):

  • 注意:從iOS7開始,系統(tǒng)為UINavigationController提供了一個(gè)interactivePopGestureRecognizer用于右滑返回(pop),但是览绿,如果自定了back button或者隱藏了navigationBar策严,該手勢(shì)就失效了。

  • 所以如果若想使用這個(gè)功能,則返回按鈕最好使用系統(tǒng)的.

若自定義了返回按鈕,又想"右滑返回的手勢(shì)有效"的解決辦法:

在UINavigationController基類中添加代碼如下:

遵守協(xié)議是 <UIGestureRecognizerDelegate>

切記:使用此方法時(shí)  self.hidesBarsOnSwipe = YES;不能使用,即默認(rèn)是關(guān)閉的,否則會(huì)造成沖突,在右滑返回時(shí) 會(huì)出現(xiàn)navigationBar不正常顯示的問題,如有興趣可自己嘗試一下.
- (void)viewDidLoad {
    [super viewDidLoad];
//    self.hidesBarsOnSwipe = YES;
//    self.toolbarHidden = NO;
    self.hidesBottomBarWhenPushed = YES;
    self.interactivePopGestureRecognizer.delegate =  self;

}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (self.viewControllers.count <= 1 ) {
        return NO;
    }
    
    return YES;
}
  • 關(guān)于右滑返回的總結(jié)是:若想使用該屬性,則最好使用系統(tǒng)返回鍵.

下面這些屬性在某些情況下會(huì)使用到

  • 在小屏4s 5s上有些PM可能會(huì)要求在瀏覽內(nèi)容時(shí)隱藏導(dǎo)航欄,這個(gè)時(shí)候就可使用此屬性.

hidesBarsOnTap(點(diǎn)擊隱藏導(dǎo)航欄,再點(diǎn)擊顯現(xiàn),皆有向上/下過度的過程)
hidesBarsOnSwipe(經(jīng)試驗(yàn)是向上輕掃隱藏,向下輕掃則顯現(xiàn),皆有向上/下過度的過程)
hidesBarsWhenVerticallyCompact
hidesBarsWhenKeyboardAppears
navigationBarHidden
barHideOnTapGestureRecognizer
barHideOnSwipeGestureRecognizer

ToolBar屬性

- setToolbarHidden:animated:
toolbarHidden

三饿敲、導(dǎo)航條

UINavigationController是做導(dǎo)航用的妻导,具體的操作大部是由導(dǎo)航條來完成,導(dǎo)航條的使用就顯得很重要怀各。導(dǎo)航條的內(nèi)容由控制器的navigationItem屬性決定倔韭。
1 navigationItem的屬性
一般使用self.navigationItem.對(duì)應(yīng)屬性來獲取屬性,或者設(shè)置屬性渠啤『或者使用self.navigationController獲取到navigationController添吗,再通過navigationController獲取到想要設(shè)置的viewController

中間的標(biāo)題文字

@property(nullable, nonatomic,copy) NSString *title;

中間標(biāo)題視圖

@property(nullable, nonatomic,strong) UIView *titleView;

項(xiàng)目中的常用方法是:

UIImageView *titleView = [[UIImageView alloc]initWithFrame:CGRectMake(SCREEN_WIDTH/2 - 100, 0, 200, 44)];
titleView.image = 圖片.
[self.navigationItem.titleView addSubview:titleView];

導(dǎo)航欄附加解釋說明沥曹,如果設(shè)置了此字段,導(dǎo)航欄會(huì)高出30個(gè)點(diǎn)顯示此字段在title正上方
@property(nullable,nonatomic,copy) NSString *prompt;
prompt顯示位置


自定義左上角的返回按鈕

/// 直接設(shè)置
@property(nullable, nonatomic,strong) UIBarButtonItem *leftBarButtonItem;

大部分情況下碟联,我們需要指定左邊返回按鈕距離左邊框的距離妓美,可以如下設(shè)定:

//自己項(xiàng)目中的方法
 UIButton *backBt = [UIButton buttonWithType:UIButtonTypeSystem];
 backBt.frame = CGRectMake(0, 0, LabelWidth_20, LabelWidth_20);
 [backBt setBackgroundImage:[UIImage imageNamed:@"回退"] forState:UIControlStateNormal];
 [backBt addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
 self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:backBt];
//系統(tǒng)推薦方法如下
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"gobackItem.png"] style:UIBarButtonItemStylePlain target:self action:@selector(backViewcontroller)];
UIBarButtonItem *fixedItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
// 設(shè)置邊框距離,個(gè)人習(xí)慣設(shè)為-16鲤孵,可以根據(jù)需要調(diào)節(jié)fixedItem.width = -16;
self.navigationItem.leftBarButtonItems = @[fixedItem, leftItem];

下圖為設(shè)置邊框距離前后的差別:

沒有設(shè)置邊框距離


設(shè)置邊框距離后


忽略點(diǎn):(關(guān)于系統(tǒng)返回按鈕)

  • 子導(dǎo)航條后退按鈕壶栋,假設(shè)通過VC1 push VC2,那么如果設(shè)置VC1.navigationItem.backBarButtonItem就會(huì)顯示在VC2的左上角返回按鈕普监;
    如果再設(shè)置VC2.navigationItem.leftBarButtonItem則會(huì)覆蓋VC1的設(shè)置贵试;
    如果VC1和VC2都沒有設(shè)置,則會(huì)顯示默認(rèn)的backBarButtonItem凯正。
@property(nullable,nonatomic,strong) UIBarButtonItem *backBarButtonItem;
  • push到下一個(gè)頁面時(shí),若不自定義返回按鈕,則會(huì)顯示默認(rèn)的返回按鈕 "<返回" 字體顏色為系統(tǒng)字體顏色,即backBarButtonItem,且系統(tǒng)的向左平移pop的功能會(huì)自己實(shí)現(xiàn).
  • 若自定義了返回按鈕 則系統(tǒng)自帶的向左平移pop的功能會(huì)失效.
  • title的長(zhǎng)度不可過長(zhǎng),否則會(huì)造成系統(tǒng)返回按鈕的 返回 字體消失,只剩余一個(gè)<

自定義右上角的按鈕毙玻,或多個(gè)按鈕

@property(nullable, nonatomic,strong) UIBarButtonItem *rightBarButtonItem;/// 一次設(shè)置多個(gè)按鈕
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *rightBarButtonItems;

2 設(shè)置navigationItem的字體格式

// 字體大小19,顏色為白色
[nav.navigationBar setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:19],NSForegroundColorAttributeName:[UIColor whiteColor]}];

四廊散、UIToolBar
UINavigationController自帶了一個(gè)工具欄桑滩,通過[self.navigationController setToolbarHidden:NO];來顯示工具欄,工具欄中的內(nèi)容可以通過viewController的toolbarItems來設(shè)置允睹,顯示的順序和設(shè)置的NSArray中存放的順序一致运准,每一個(gè)UIBarButtonItem對(duì)象都可以設(shè)定點(diǎn)擊事件幌氮,可以使用系統(tǒng)提供的很多常用風(fēng)格的對(duì)象,也可以根據(jù)需求進(jìn)行自定義胁澳,下面舉例使用系統(tǒng)提供的樣式该互。

// 1 顯示工具條
[self.navigationController setToolbarHidden:NO];
// 2 創(chuàng)建四個(gè)UIBarButtonItem
UIBarButtonItem *itemOne = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
UIBarButtonItem *itemTwo = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:nil action:nil];
UIBarButtonItem *itemThree = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];
UIBarButtonItem *itemFour = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:nil action:nil];
// 間隙
UIBarButtonItem *flexibleItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
// 3 添加到toolbarItemsvc.
toolbarItems = @[itemOne,flexibleItem,itemTwo,flexibleItem,itemThree,flexibleItem,itemFour];

效果如下:


另外,UIToolBar使用的比較少韭畸,大部分情況下而是使用另一個(gè)導(dǎo)航控制器UITabBarController

五 UINavigationControllerDelegate

有兩個(gè)常用的方法

// 一般用于傳遞參數(shù)慢洋,或者做一些其它處理
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;

參考:http://www.cnblogs.com/mddblog/p/4556974.html

六 UINavigationBar、UINavigationItem陆盘、UIToolbar與UIBarButtonItem四者關(guān)系

補(bǔ)充:

1 三者概述

  • UITabBar 上展示的是: UITabBarItem( 其類繼承關(guān)系為--> UIBarItem --> NSObject)

  • UIToolBar 上展示的是: UIToolBarItem (其類繼承關(guān)系為-->UIBarButtonItem --> UIBarItem--> NSObject)

  • UINavigationBar 上展示的是: UINavigationItem(包括:titleView leftBarButtonItem leftBarButtonItems rightBarButtonItem rightBarButtonItems) (其類繼承關(guān)系為--> UIBarButtonItem --> UIBarItem--> NSObject)

2 三者區(qū)別

名稱 位置 作用 高度 appearance
UITabBar 任意位置(常見底部) 點(diǎn)擊前后item發(fā)生變化,管理一組視圖 49 全局修改UI
UIToolBar 任意位置(常見底部) 一般用作功能性點(diǎn)擊 44 全局修改UI
UINavigationBar 頂部 一般初始化UINavigationController時(shí),自動(dòng)生成UIUINavigationBar,也可以單獨(dú)使用 44 全局修改UI

NavigaitonBar
是導(dǎo)航欄普筹,位于屏幕的上方,管理整個(gè)NavigationController的navigationItem隘马,它類似navigationcontroller一樣提供了一個(gè)棧來管理UINavigationItem太防,在編程時(shí),一般只設(shè)置每個(gè)控制器的navigationItem屬性.一個(gè)導(dǎo)航控制器管理多個(gè)視圖控制器(多個(gè)視圖控制器共享一個(gè)導(dǎo)航控制器)酸员,而一個(gè)導(dǎo)航控制器只有一個(gè)UINavigationBar蜒车,被管理的多個(gè)視圖控制器共享這一個(gè)UINavigationBar,只要一個(gè)視圖控制器改變了UINavigationBar的屬性則影響是全局的幔嗦。每個(gè)視圖控制器都會(huì)有屬于自己的UINavigationItem酿愧,系統(tǒng)會(huì)以懶加載的方式創(chuàng)建一個(gè)UINavigationItem顯示在UINavigationBar中,改變UINavigationItem
只會(huì)在當(dāng)前控制器起作用邀泉,不會(huì)影響其它控制器嬉挡。

Toolbar
顯示在屏幕底部,是導(dǎo)航控制器的工具欄汇恤,一個(gè)導(dǎo)航控制器只有一個(gè)庞钢,在任何被管理的視圖控制器地方改變則會(huì)都改變∫蚧眩可以一次性添加多個(gè)UIBarButtonItem或按鈕(包裝成UIBarButtonItem后添加)基括,有一個(gè)items數(shù)組屬性。

UIBarButtonItem
是UINavigationItem或者Toolbar具體的一個(gè)按鈕财岔。

UITabBar外觀相關(guān)的屬性和方法:

自定義TabBar的方法參考:

barStyle
The tab bar style that specifies its appearance.

translucent
A Boolean value that indicates whether the tab bar is translucent.

barTintColor
The tint color to apply to the tab bar background.

itemPositioning
The positioning scheme for the tab bar items in the tab bar.

itemSpacing
The amount of space (in points) to use between tab bar items.

itemWidth
The width (in points) of tab bar items.

tintColor
The tint color to apply to the tab bar items.

backgroundImage
The custom background image for the tab bar.

shadowImage
The shadow image to use for the tab bar.

selectionIndicatorImage
The image to use for the selection indicator.

UINavigationBar外觀相關(guān)的屬性和方法:
backIndicatorImage
The image shown beside the back button.

backIndicatorTransitionMaskImage
The image used as a mask for content during push and pop transitions.

barStyle
The navigation bar style that specifies its appearance.

barTintColor
The tint color to apply to the navigation bar background.

shadowImage
The shadow image to be used for the navigation bar.

tintColor
The tint color to apply to the navigation items and bar button items.

translucent
A Boolean value indicating whether the navigation bar is translucent (YES
) or not (NO
).

- backgroundImageForBarMetrics:
Returns the background image for given bar metrics.

- setBackgroundImage:forBarMetrics:
Sets the background image for given bar metrics.

- backgroundImageForBarPosition:barMetrics:
Returns the background image to use for a given bar position and set of metrics.

- setBackgroundImage:forBarPosition:barMetrics:
Sets the background image to use for a given bar position and set of metrics.

- titleVerticalPositionAdjustmentForBarMetrics:
Returns the title’s vertical position adjustment for given bar metrics.

- setTitleVerticalPositionAdjustment:forBarMetrics:
Sets the title’s vertical position adjustment for given bar metrics.

titleTextAttributes
Display attributes for the bar’s title text.

UIToolBar外觀相關(guān)的屬性和方法:
barStyle
The toolbar style that specifies its appearance.

barTintColor
The tint color to apply to the toolbar background.

tintColor
The tint color to apply to the bar button items.

translucent
A Boolean value that indicates whether the toolbar is translucent (YES
) or not (NO
).

- backgroundImageForToolbarPosition:barMetrics:

- setBackgroundImage:forToolbarPosition:barMetrics:

- shadowImageForToolbarPosition:

- setShadowImage:forToolbarPosition:

關(guān)于詳細(xì)使用方法可參考:UINavigationBar 使用總結(jié):寫的很詳細(xì).

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末风皿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子匠璧,更是在濱河造成了極大的恐慌桐款,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件患朱,死亡現(xiàn)場(chǎng)離奇詭異鲁僚,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門冰沙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侨艾,“玉大人,你說我怎么就攤上這事拓挥∵肜妫” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵侥啤,是天一觀的道長(zhǎng)当叭。 經(jīng)常有香客問我,道長(zhǎng)盖灸,這世上最難降的妖魔是什么蚁鳖? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮赁炎,結(jié)果婚禮上醉箕,老公的妹妹穿的比我還像新娘。我一直安慰自己徙垫,他們只是感情好讥裤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著姻报,像睡著了一般己英。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吴旋,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天损肛,我揣著相機(jī)與錄音,去河邊找鬼邮府。 笑死荧关,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的褂傀。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼加勤,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼仙辟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鳄梅,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤叠国,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后戴尸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粟焊,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了项棠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悲雳。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖香追,靈堂內(nèi)的尸體忽然破棺而出合瓢,到底是詐尸還是另有隱情,我是刑警寧澤透典,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布晴楔,位于F島的核電站,受9級(jí)特大地震影響峭咒,放射性物質(zhì)發(fā)生泄漏税弃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一凑队、第九天 我趴在偏房一處隱蔽的房頂上張望钙皮。 院中可真熱鬧,春花似錦顽决、人聲如沸短条。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茸时。三九已至,卻和暖如春赋访,著一層夾襖步出監(jiān)牢的瞬間可都,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工蚓耽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留渠牲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓步悠,卻偏偏與公主長(zhǎng)得像签杈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鼎兽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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