導航控制器(UINavigationController)


導航控制器管理一系列顯示層次型信息的場景。它創建一個視圖管理器"棧",棧底為根視圖控制器,用戶在場景間切換時,依次將試圖控制器壓入棧中,且當前場景的試圖控制器位於棧頂。要返回上一級,導航控制器將彈出棧頂的控制器,從而回到它下面的控制器。

導航控制器還管理一個導航欄(UINavigationBar)。導航欄類似於工具欄,但它是使用導航項(UINavigationItem)實例填充的,該實例被加入到導航控制器管理的每個場景中。默認情況下,場景的導航項包含一個標題和一個Back按鈕。Back按鈕是以欄按鈕項(UIBarButtonItem)的方式加入到導航項的。

導航項在Attributes inspector面板里有三個可設置屬性:Title、Prompt和Back Button
Title -- 導航項的標題
Prompt -- 顯示在標題上方的文本,向用戶提供使用說明
Back Button -- 下一個場景的后退按鈕的文本,假如沒有設置,默認顯示的文本是標題

在任何場景中,都可通過屬性parentViewController來獲取導航控制器。

UINavigationController分為三個部分:頂部的Navigation Bar,中間的Custom Content以及底部的Navigation toolbar。如圖所示:

代碼添加UINavigationController:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    UIViewController *firstVC = [[UIViewController alloc] initWithNibName:@"FirstVC" bundle:nil];
    
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstVC];
    
    self.window.rootViewController = navigationController;
    self.window.backgroundColor = [UIColor greenColor];
    [self.window makeKeyAndVisible];

    SecondVC *secondVC = [[SecondVC alloc] init];
    ThirdVC *thirdVC = [[ThirdVC alloc] init];
    NSArray *array = @[secondVC, thirdVC];
    [navigationController setViewControllers:array animated:YES];
    
    [navigationController pushViewController:firstVC animated:YES];
    
    return YES;
}

 

UIViewController的navigationItem屬性

添加navigationItem是UIViewController的一個屬性,這個屬性是為UINavigationController服務的。這個屬性包含以下幾個界面元素:

leftBarButtonItem -- 左按鈕

rightBarButtonItem -- 右按鈕

backBarButtonItem -- 返回按鈕

title -- 標題

prompt -- 提示

UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:@"LeftButton" style:UIBarButtonItemStylePlain target:self action:@selector(test1)];
firstVC.navigationItem.leftBarButtonItem = leftButton;

UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:@"RightButton" style:UIBarButtonItemStylePlain target:self action:@selector(test1)];
firstVC.navigationItem.rightBarButtonItem = rightButton;

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"BackButton" style:UIBarButtonItemStylePlain target:self action:@selector(test1)];
firstVC.navigationItem.backBarButtonItem = backButton;

firstVC.navigationItem.title = @"My Title";
//firstVC.navigationItem.titleView = [[UIView alloc] init];

firstVC.navigationItem.prompt = @"Just A Prompt";

   

 

leftBarButtonItemrightBarButtonItem可以指定多個按鈕,backButton只能指定一個按鈕。

設定了prompt會增加NavigationBar的高度。

要進一步自定義title,可以通過titleView屬性將title設置成一個自定義的UIView。

通過設定navigationItem.leftItemsSupplementBackButton = YES可以同時顯示leftBarButtonItembackBarButtonItem

添加單個按鈕:

UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:@"編輯" style:UIBarButtonItemStylePlain target:self action:@selector(test1)];
    
NSDictionary *attributes = @{NSFontAttributeName: [UIFont fontWithName:@"TimesNewRomanPS-BoldMT" size:14.0f],
                             NSForegroundColorAttributeName: [UIColor greenColor]};

[rightButton setTitleTextAttributes:attributes forState:UIControlStateNormal];

firstVC.navigationItem.rightBarButtonItem = rightButton;

添加多個按鈕:

UIBarButtonItem *cleanButton = [[UIBarButtonItem alloc] initWithTitle:@"清空"
                                                                style:UIBarButtonItemStylePlain
                                                               target:self
                                                               action:@selector(cleanTextView)];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:@"保存"
                                                               style:UIBarButtonItemStylePlain
                                                              target:self
                                                              action:@selector(saveTextView)];

firstVC.navigationItem.rightBarButtonItems = @[cleanButton, saveButton];

P.s. UIBarButtonItemStylePlainUIBarButtonItemStyleDone的區別就是后者字體更粗而已。

 

利用navigationController.navigationBar.titleTextAttributes屬性修改文本外觀

NSDictionary *dict = [NSDictionary dictionaryWithObject:[UIColor greenColor] forKey:NSForegroundColorAttributeName];
navigationController.navigationBar.titleTextAttributes = dict;

 

UIViewController的edgesForExtendedLayout屬性與extendedLayoutIncludesOpaqueBars屬性

這也是兩個與UINavigationController有關聯的屬性:

edgesForExtendedLayout — 這個屬性屬於UIExtendedEdge類型,它指定了視圖的哪條邊需要擴展開;默認值是UIRectEdgeAll(全部擴展),也可以通過UIRectEdgeLeft|UIRectEdgeRight這種方式設定部分擴展定、或設定為UIRectEdgeNone(全部不擴展)。

假如childVC有一個Y坐標為100的子控件,當edgesForExtendedLayout包含了UIRectEdgeTop時,它是從最頂端開始計算Y坐標;否則是從Navigationbar的offsetY開始計算Y坐標。

extendedLayoutIncludesOpaqueBars — 這個屬性指定了當Navigationbar使用了不透明圖片時,視圖是否延伸至Bar所在區域,默認值時NO(不延伸)。當Navigationbar並未使用不透明圖片做背景時,該屬性無效。

Navigationbar使用了不透明圖片當背景時,各種情況如下:

1. edgesForExtendedLayout默認值(UIRectEdgeAll) && extendedLayoutIncludesOpaqueBars默認值(NO)

雖然edgesForExtendedLayout包含了UIRectEdgeTop,但由於是不透明圖片做背景,並且extendedLayoutIncludesOpaqueBars設定了不延伸,這個時候子控件的Y坐標還是從NavigationbaroffsetY開始計算。當隱藏navigationBar時(navigationController.navigationBarHidden = YES),childVC會整體上移

2. edgesForExtendedLayout默認值(UIRectEdgeAll) && extendedLayoutIncludesOpaqueBars為YES

雖然是不透明圖片做背景,但extendedLayoutIncludesOpaqueBars設定為延伸,這個時候子控件的Y坐標是從最頂端計算。當隱藏navigationBar時childVC不會改變位置。

可以通過下面的代碼來驗證這兩個屬性的各種搭配情況:

CGSize imageSize = CGSizeMake(1, 1);
UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);
[[UIColor greenColor] set];
UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
[path fill];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext ();
UIGraphicsEndImageContext();

[[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];

firstVC.edgesForExtendedLayout = UIRectEdgeNone;

firstVC.extendedLayoutIncludesOpaqueBars = YES;

 

UINavigationController底部的ToolBar

UIBarButtonItem *one = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
UIBarButtonItem *two = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:nil action:nil];
UIBarButtonItem *three = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];

navigationController.toolbarHidden = NO;
[firstVC setToolbarItems:[NSArray arrayWithObjects:one, two, three, nil] animated:YES];

 

UINavigationControllerDelegate

該代理的兩個主要方法如下,主要作用是在切換前對目標ViewController進行設置:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    NSLog(@"%@",viewController);
    viewController.view.backgroundColor = [UIColor greenColor];
    NSLog(@"willShowViewController");
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    NSLog(@"%@",viewController);
    NSLog(@"didShowViewController");
}

 

UINavigationControllertopViewControllervisibleViewController屬性

topViewController — 獲取頂層ViewController

visibleViewController — 獲取當前顯示的ViewController

絕大多數情況下,topViewController是等於visibleViewController的,對於在topViewController上通過presentViewController跳轉到一個新的ViewController情況,topViewController是不等於visibleViewController的。


免責聲明!

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



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