iOS中UINavigationController控制器使用詳解


一、概述

UINavigationController用來管理視圖控制器,在多視圖控制器中常用。它以棧的形式管理視圖控制器,管理視圖控制器個數理論上不受限制(實際受內存限制),pushpop方法來彈入彈出控制器,最多只能顯示一個視圖控制器,那就是處於棧頂的視圖控制器。

一般情況下,UINavigationController最少管理一個控制器,即最少有一個根視圖控制器或者叫做棧底視圖控制器。當然也有例外,如果不給它添加視圖控制器也不會報錯,界面上也有視圖,因為UINavigationController繼承自UIViewController,也有自己的view,只不過默認情況下.view.backgroundColor為nil,即透明的。

二、常用函數

  • 使用push方法能將某個控制器壓入棧
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
  • 使用setViewControllers一次壓入多個控制器vc1->vc2->vc3,會顯示最后的控制器vc3(處於棧頂),代碼如下:
UINavigationController *nav = [[UINavigationController alloc] init];
window.rootViewController = nav;
// 創建3個測試控制器
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];
// 最終會顯示vc3
[nav setViewControllers:@[vc1,vc2,vc3] animated:YES];
  • 使用pop方法可以移除棧頂控制器 

當一個控制器被pop后,控制器內存就被釋放了(會調用deinit/dealloc函數):

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

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

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

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

-(NSArray *)popToRootViewControllerAnimated:(BOOL)animated;
  • 獲取控制器
/// 當前管理的所有的控制器
@property(nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers;

/// 棧頂控制器
@property(nullable, nonatomic,readonly,strong) UIViewController *topViewController;

/// 當前可見的VC,可能是topViewController,也可能是當前topViewController present(modal)出來的VC,總而言之就是可見的VC
@property(nullable, nonatomic,readonly,strong) UIViewController *visibleViewController;

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

三、導航條

UINavigationController是做導航用的,具體的操作大部是由導航條來完成,導航條的使用就顯得很重要。導航條的內容由控制器的navigationItem屬性決定。 

1 navigationItem的屬性

一般使用self.navigationItem.對應屬性來獲取屬性,或者設置屬性。或者使用self.navigationController獲取到navigationController,再通過navigationController獲取到想要設置的viewController

  • 中間的標題文字
@property(nullable, nonatomic,copy) NSString *title;
  • 中間標題視圖
@property(nullable, nonatomic,strong) UIView *titleView;
  • 導航欄附加解釋說明,如果設置了此字段,導航欄會高出30個點顯示此字段在title正上方
@property(nullable,nonatomic,copy)   NSString *prompt;

prompt顯示位置

  • 自定義左上角的返回按鈕
/// 直接設置
@property(nullable, nonatomic,strong) UIBarButtonItem *leftBarButtonItem;

大部分情況下,我們需要指定左邊返回按鈕距離左邊框的距離,可以如下設定:

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];
// 設置邊框距離,個人習慣設為-16,可以根據需要調節
fixedItem.width = -16;
self.navigationItem.leftBarButtonItems = @[fixedItem, leftItem];

下圖為設置邊框前后的差別:

 沒有設置

設置后

  • 子導航條后退按鈕,假設通過VC1pushVC2,那么如果設置VC1.navigationItem.backBarButtonItem就會顯示在VC2的左上角返回按鈕;如果再設置VC2.navigationItem.leftBarButtonItem則會覆蓋VC1的設置;如果VC1和VC2都沒有設置,則會顯示默認的backBarButtonItem
@property(nullable,nonatomic,strong) UIBarButtonItem *backBarButtonItem;
  • 自定義右上角的按鈕,或多個按鈕
@property(nullable, nonatomic,strong) UIBarButtonItem *rightBarButtonItem;
/// 一次設置多個按鈕
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *rightBarButtonItems;

2 設置navigationItem的字體格式

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

四、UIToolBar

UINavigationController自帶了一個工具欄,通過[self.navigationController setToolbarHidden:NO];來顯示工具欄,工具欄中的內容可以通過viewControllertoolbarItems來設置,顯示的順序和設置的NSArray中存放的順序一致,每一個UIBarButtonItem對象都可以設定點擊事件,可以使用系統提供的很多常用風格的對象,也可以根據需求進行自定義,下面舉例使用系統提供的樣式。

// 1 顯示工具條
[self.navigationController setToolbarHidden:NO];
// 2 創建四個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 添加到toolbarItems
vc.toolbarItems = @[itemOne,flexibleItem,itemTwo,flexibleItem,itemThree,flexibleItem,itemFour];

效果如下:

 

另外,UIToolBar使用的比較少,大部分情況下而是使用另一個導航控制器UITabBarController

五 UINavigationBar、UINavigationItem、UIToolbar與UIBarButtonItem四者關系

  • NavigaitonBar是導航欄,位於屏幕的上方,管理整個NavigationControllernavigationItem,它類似navigationcontroller一樣提供了一個棧來管理UINavigationItem,在編程時,一般只設置每個控制器的navigationItem屬性
  • 一個導航控制器管理多個視圖控制器(多個視圖控制器共享一個導航控制器),而一個導航控制器只有一個UINavigationBar,被管理的多個視圖控制器共享這一個UINavigationBar,只要一個視圖控制器改變了UINavigationBar的屬性則影響是全局的。每個視圖控制器都會有屬於自己的UINavigationItem,系統會以懶加載的方式創建一個UINavigationItem顯示在UINavigationBar中,改變UINavigationItem只會在當前控制器起作用,不會影響其它控制器。
  • Toolbar顯示在屏幕底部,是導航控制器的工具欄,一個導航控制器只有一個,在任何被管理的視圖控制器地方改變則會都改變。可以一次性添加多個UIBarButtonItem或按鈕(包裝成UIBarButtonItem后添加),有一個items數組屬性。
  • UIBarButtonItemUINavigationItem或者Toolbar具體的一個按鈕。

六、UINavigationControllerDelegate

有兩個常用的方法

// 一般用於傳遞參數,或者做一些其它處理
- (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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM