导航控制器(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";

leftBarButtonItem和rightBarButtonItem可以指定多个按钮,backButton只能指定一个按钮。
设定了prompt会增加NavigationBar的高度。
要进一步自定义title,可以通过titleView属性将title设置成一个自定义的UIView。
通过设定navigationItem.leftItemsSupplementBackButton = YES可以同时显示leftBarButtonItem和backBarButtonItem。
添加单个按钮:
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. UIBarButtonItemStylePlain和UIBarButtonItemStyleDone的区别就是后者字体更粗而已。
利用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坐标还是从Navigationbar的offsetY开始计算。当隐藏navigationBar时(navigationController.navigationBarHidden = YES),childVC会整体上移
2. edgesForExtendedLayout默认值(UIRectEdgeAll) && extendedLayoutIncludesOpaqueBars为YES
虽然是不透明图片做背景,但extendedLayoutIncludesOpaqueBars设定为延伸,这个时候子控件的Y坐标是从最顶端计算。当隐藏navigationBar时childVC不会改变位置。
可以通过下面的代码来验证这两个属性的各种搭配情况:
CGSize imageSize = CGSizeMake(, );
UIGraphicsBeginImageContextWithOptions(imageSize, YES, );
[[UIColor greenColor] set];
UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(, , 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");
}
UINavigationController的topViewController与visibleViewController属性
topViewController — 获取顶层ViewController
visibleViewController — 获取当前显示的ViewController
绝大多数情况下,topViewController是等于visibleViewController的,对于在topViewController上通过presentViewController跳转到一个新的ViewController情况,topViewController是不等于visibleViewController的。
导航控制器(UINavigationController)的更多相关文章
- iOS开发UINavigation——导航控制器UINavigationController
iOS开发UINavigation系列一——导航栏UINavigtionBar摘要iOS中的导航条可以附着于导航控制器之中使用,也可以在controller中单独使用,这篇博客,主要讨论有关导航栏的使 ...
- 利用协议代理实现导航控制器UINavigationController视图之间的正向传值和反向传值
实验说明 (1)正向传值:比如A类里地值要传给B类用,就是我们先在A类中声明一个B类对象(当然B类头文件要import过来),然后把A类中得某个 值传递给B类中得某个值(所以需要在B类中先准备一个变量 ...
- IOS UINavigationController 导航控制器
/** 导航控制器掌握: 1.创建导航控制器 UINavigationController *nav = [[UINavigationController alloc] initWithRootVie ...
- IOS第12天(2,UINavigationController导航控制器)
****HMAppDelegate.m @implementation HMAppDelegate - (BOOL)application:(UIApplication *)application d ...
- UINavigationController 导航控制器 ,根据文档写的一些东西
今天讲了导航控制器UINavigationController 和标签栏视图控制器UITabBarController 先来说一说导航视图控制器 UINavigationController 导航控 ...
- IOS 导航控制器基本使用(UINavigationController代码创建方式)
● UINavigationController的使用步骤 ➢ 初始化UINavigationController ➢ 设置UIWindow的rootViewController为UINavigati ...
- iOS开发UI篇—多控制器和导航控制器简单介绍
iOS开发UI篇—多控制器和导航控制器简单介绍 一.多控制器 一个iOS的app很少只由一个控制器组成,除非这个app极其简单.当app中有多个控制器的时候,我们就需要对这些控制器进行管理 有多个vi ...
- IOS开发UI篇—导航控制器属性和基本使用
IOS开发UI篇—导航控制器属性和基本使用 一.导航控制器的一些属性和基本使用 1.把子控制器添加到导航控制器中的四种方法 (1) 1.创建一个导航控制器 UINavigationController ...
- IOS开发-表视图LV3导航控制器
学到这里感觉有点难了,其实这篇文章再草稿箱里放了好久了~ 最近对于学习的热情下降了.这不行-抓紧学习走起! 在这一章节的学习中主要针对导航控制器及表视图来建立多视图的应用, 首先要了解一些概念-- 1 ...
随机推荐
- 782C. Andryusha and Colored Balloons DFS
Link 题意: 给出一棵树,要求为其染色,并且使任意节点都不与距离2以下的节点颜色相同 思路: 直接DFS.由某节点出发的DFS序列,对于其个儿子的cnt数+1,那么因为DFS遍历的性质可保证兄弟结 ...
- 51nod 1140 矩阵相乘结果的判断
给出三个N*N的矩阵A, B, C,问A * B是否等于C? Input 第1行,1个数N.(0 <= N <= 500) 第2 - N + 1行:每行N个数,对应矩阵A的元素.(0 ...
- $this->success()传值不完整
public function manager_doExport() { $search=$_POST['search']; //前台输入2017-12-1,即,$search['starttime' ...
- 浅析 Spring Aop
aop也是Spring里比较重要的一个点,最近把源码看了下,这里总结一下 使用上主要就下面的点注意下: 相关的Annotaion Around Before After AfterReturning ...
- 【洛谷 P2512】 [HAOI2008]糖果传递(贪心)
题目链接 环形均分纸牌. 设平均数为\(ave\),\(g[i]=a[i]-ave\),\(s[i]=\sum_{j=1}^ig[i]\). 设\(s\)的中位数为\(s[k]\),则答案为\(\su ...
- 天梯赛 L1-009 N个数求和 (模拟)
本题的要求很简单,就是求N个数字的和.麻烦的是,这些数字是以有理数"分子/分母"的形式给出的,你输出的和也必须是有理数的形式. 输入格式: 输入第一行给出一个正整数N(<=1 ...
- Redis数据类型之列表(list)
1. 什么是列表 redis的列表使用双向链表实现,往列表中放元素的时候复杂度是O(1),但是随机访问的时候速度就不行了,因为需要先遍历到指定的位置才可以取到元素. 既然列表是使用链表实现的,那么就说 ...
- 通过cordova将vue项目打包为webapp
准备工作:需要之前配置好vue-cli脚架构,安装好cordova环境.下面开始对vue.js项目进行打包,打包环境为Android. 可以看下我的github:https://github.com/ ...
- python并发编程之gevent协程(四)
协程的含义就不再提,在py2和py3的早期版本中,python协程的主流实现方法是使用gevent模块.由于协程对于操作系统是无感知的,所以其切换需要程序员自己去完成. 系列文章 python并发编程 ...
- glom模块的使用(二)
上次我们说到golm的简单应用这次我们继续带结构化数据的其他操作进行学习. Literal 用法:class glom.Literal(value) 这个方法的功能主要是添加自定义的键值. 例如: f ...