一蹋凝、概述
- 類繼承關(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ù):
- 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ì)有效"的解決辦法:
- 方法一:在視圖基類中自定義手勢(shì)返回,但是沒有系統(tǒng)的漸變的效果.博主不推薦使用該方法.
- 網(wǎng)上查的解決辦法是:UINavigationController返回手勢(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)的屬性和方法:
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ì).