iOS UIKit:Navigation Controllers
navigation controller是一种层次结构的container view controller,即其通过一个view controllers栈来管理内部的content view controllers。如图 11所示最上两层属于Navigation view的层次结构。
图 11 The views of a navigation interface
1 组成对象
Navigation Controller通过使用一些对象来实现交互的接口,用户(软件工程师)负责提供这些对象,而其余的由Navigation Controller自身实现。特别是需要显示的content view controllers,若需接收消息,还可以提供delegate对象。
如图 12所示的组成对象。用户仅可以修改navigation bar 和toolbar对象的部分行为和显示内容;其中对于UINavigationBar对象,Navigation Controller将自身设置为其delegate,从而保证不被改变。
图 12 Objects managed by the navigation controller
注意:
用户提供的content view controllers是按先进后出的顺序进行操作的,并且在栈中的第一个view controller是无法被弹出的,将该view controller称为root view controller。
2 创建Navigation
2.1 Storyboard方式
使用Xcode的Storyboard方式创建Navigation Controller非常简单,一般不需用户再配置过多的内容。可以按如下的步骤进行创建:
a) 从library中拖动一个navigation controller控价。
b) Interface Builder会自动创建一对controller:navigation controller 和view controller。其将该view controller自动配置为root view controller。如图 13所示。
图 13 navigation controller控价
c) 若需要修改navigation controller的root view controller,那么可以在Attributes inspector中修改其"root view controller"属性。
图 14 修改navigation 的root view cotroller
d) 若需要后续再添加新的content view controller,只需在某个响应对象中"show"一个view controller即可,从而当单击该对象即可弹出新的view controller,并将其添加到栈顶。如图 15所示。
图 15 在navigation controller层次结构中添加新的content view controller
e) 若需要修改新的content view controller的返回按钮内容,可以选中其上级的view controller的navigation item,从而在Attributes inspector中修改返回按钮的显示内容。如图 16和图 17所示。
图 16 返回按钮设计图
图 17 展示效果图
2.2 Program方式
通过程序方式创建navigation也不是非常难,由于导航其实是一个UINavigationController控制器类。所以若创建一个navigation,只需创建一个UINavigationController对象,然后将其添加为某个view controller的层次结构中。其中需要注意的是在创建UINavigationController对象时,需要传递一个root view controller对象。
如下所示:
1 @interface ViewController : UIViewController
2 @property UINavigationController *navigationController;
3 @end
4 @implementation ViewController
5 - (void)viewDidLoad {
6 [super viewDidLoad];
7 // Do any additional setup after loading the view, typically from a nib.
8 UIViewController* customVC = [self.storyboard instantiateViewControllerWithIdentifier:@"customRoot"];
9 _navigationController = [[UINavigationController alloc] initWithRootViewController:customVC];
10
11 [self addChildViewController:_navigationController];
12 [self.view addSubview:_navigationController.view];
13 }@end
3 Navigation控制
3.1 全屏配置
Navigation视图中的content view controller的显示位置默认都是在navigation bar 和toolbar(tab bar)之间,若需要配置全屏的显示方式,需要做如下的配置:
a) 设置顶层的window (或parent view)为全屏显示;
b) 隐藏navigation bar,即将navigation controller的translucent属性设置为YES;若在Interface Builder中可以去掉Attributes inspector中选项的勾选;
c) 隐藏toolbar,即将toolbar的translucent属性设置为YES;若在Interface Builder中可以去掉Attributes inspector中选项的勾选;
d) 将content view controller的wantsFullScreenLayout属性设置为YES。
3.2 栈操作
Navigation中的栈是用于存放Content View Controller,而栈顶的Content VC是当前屏幕的显示视图。UIKit提供如表 11所示的几种方式来管理栈内容,即几种入栈和出栈的操作。
表 11 Options for managing the navigation stack
场景 |
描述 |
显示层次结构的下一层content(入栈) |
用户可以使用segue或者是pushViewController:animated:方法将新content view controller压入栈中,从而在屏幕中显示这个新入栈的VC。 |
退出层次结构中的栈顶元素(出栈) |
可以直接通Navigation controller的"返回按钮"弹出栈顶的content view controller,即从栈中移除该view controller;也可以以程序的方式调用popViewControllerAnimated:方法。 |
返回到之前的栈元素(入栈或出栈) |
可以通过setViewControllers:animated:方法返回到之前的状态,若指定的VC在栈中,则弹出之山的元素,将指定VC作为栈顶元素;若指定VC不在栈中,则将VC入栈。 |
返回到root VC(出栈) |
可以使用popToRootViewControllerAnimated:方法,返回到root view controller,即除了root VC,将栈中所有的content view controller都弹出。 |
返回到指定的content VC(出栈) |
可以使用popToViewController:animated:方法一次性弹出多个content view controller,直到指定的view controller为栈顶元素,即将指定的view cotroller作为栈顶元素。 |
3.3 栈状态监听
不管什么时候对Navigation中的栈进行入栈和出栈操作,都会向content view controller元素和delegate对象发生消息,从而提醒栈中的状态发生变化。如图 18所示,当进行入栈操作时,会向栈顶元素发送viewWillDisapper消息,及向新插入的元素发送viewWillAppear消息,同时也向delegate对象发送willShowViewController消息;当完成出入栈操作时,还会向相应元素发送didXXX消息。
图 18 Messages sent during stack changes
4 定制Navigation Bar
4.1 层次结构
4.1.1 UINavigationBar类型
Navigation Bar类似Navigation Container,其内部也拥有一个栈,不同的是Navigation Bar栈中元素类型是UINavigationItem类型。如图 19所示中的UINavigationBar类中的items为NSArray的数组,其指向Navigation item stack(即为Navigation Bar栈);而bar的Delegate指向UINavigationController对象;topItem指向栈顶的元素,backItem指向栈顶下的元素(即栈中第二个元素)。
图 19 navigation bar成员结构
4.1.2 UINavigationItem类型
Navigation bar栈与Navigation栈是同时进行入栈出栈操作,在Navigation栈中的Content View Controller元素都有一个UINavigationItem类型的navigationItem属性,所以Navigation中的每个Content View Controller都拥有一个独立UINavigationItem对象,而每一个UINavigationItem又有三个位置显示数据:左、中和右,如图 110所示。
图 110 UINavigationItem结构
其实对于UINavigationItem类,其成员有许多成员属性,可位于导航栏的左、中和右位置,如表 12所示。
表 12 UINavigationItem类成员属性
可显示位置 |
属性名 |
类型 |
描述 |
左侧 |
backBarButtonItem |
UIBarButtonItem |
在NavigationBar左边中默认设置一个返回到上一级(Navigation栈的下一层)按钮,此属性就是为这个功能。若自定义了左边导航项,则该项不显示。 |
leftBarButtonItems |
NSArray<UIBarButtonItem*> |
此属性为一个UIBarButtonItem类型的数组,当向导航栏左侧添加多个控件时,则由该属性存储。 |
|
leftBarButtonItem |
UIBarButtonItem |
当左边只有一项时,则显示此属性。 |
|
中侧 |
titleView |
UIView |
其为UIView类似,与其它项类型不同。默认是显示UINavigationItem对象的标题名。 |
右侧 |
rightBarButtonItems |
NSArray<UIBarButtonItem *> |
此属性为一个UIBarButtonItem类型的数组,当向导航栏右侧添加多个控件时,则由该属性存储。 |
rightBarButtonItem |
UIBarButtonItem |
当右侧只有一项时,则显示此属性。 |
4.1.3 UIBarButtonItem类型
UIBarButtonItem类型是才是存放控价的容器,其具有多种属性,具体表示语义如表 13所示。
表 13 UIBarButtonItem类的成员列表
属性名 |
类型 |
描述 |
customView |
UIView |
自定义控件就存储在该属性中。 |
action |
SEL |
为指定的响应方法地址 |
target |
id |
action响应方法所在的对象 |
width |
CGFloat |
控件的宽度 |
style |
UIBarButtonItemStyle |
控件的类型 |
4.2 配置导航项
4.2.1 配置规则
可以自定义view controller中的导航栏(UINavigationItem),但其三个位置的修改有一定的规则:
1) 左边位置
- 如果没有自定义左边的位置,那么将显示backBarButtonItem属性,即回退按钮;
- 如果自定义了左边位置,即设置了leftBarButtonItem属性,则显示自定义控件;
2) 中间位置
- 如果没有自定义中间位置,则显示title属性;
- 如果自定义了中间位置,则显示自定义的控件。
3) 右边位置
- 如果没有在自定义右边的位置,则什么也不显示;
- 如果自定义了右边的位置,即设置rightBarButtonItem属性,则显示自定义的控件。
4.2.2 Storyboard方式
可以直接从interface Builder库中直接拖动一个UIView或其子类到导航栏的三个位置之一中,并且由于Navigation栈中元素(view controller)都有一个UINavigationItem,所以彼此之间互不影响。如图 111所示的启动效果图。
图 111 导航栏配置效果图
注意:
目前测试可以直接拖动到导航栏的控件有:Button、Segmented control、text field、Slider、Switch、Progress View、UIView。
4.2.3 Program方式
采用程序方式配置导航栏也非常简单,只需从view controller中获取UINavigationItem对象,接着在其三个位置中设置一个UIBarButtonItem对象即可。如下所示。
1 - (IBAction)btnDown:(id)sender
2 {
3 UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:
4 [NSArray arrayWithObjects:
5 @"hello",
6 @"world",
7 nil]];
8 UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
9 self.navigationItem.rightBarButtonItem = segmentBarItem;
10 }
5 参考文献
[1] View Controller Catalog for IOS
iOS UIKit:Navigation Controllers的更多相关文章
- iOS UIKit:viewController之动画(5)
当弹出一个view controller时,UIKit提供了一些标准转换动画,并且也支持用户自定义的动画效果. 1 UIView动画 UIView是自带动画实现功能,其中有两种方式实现: ...
- 从零开始学ios开发(十六):Navigation Controllers and Table Views(下)
终于进行到下了,这是关于Navigation Controllers和Table Views的最后一个例子,稍微复杂了一点,但也仅仅是复杂而已,难度不大,我们开始吧. 如果没有上一篇的代码,可以从这里 ...
- 从零开始学ios开发(十四):Navigation Controllers and Table Views(上)
这一篇我们将学习一个新的控件Navigation Controller,很多时候Navigation Controller是和Table View紧密结合在一起的,因此在学习Navigation Co ...
- 从零开始学ios开发(十五):Navigation Controllers and Table Views(中)
这篇内容我们继续上一篇的例子接着做下去,为其再添加3个table view的例子,有了之前的基础,学习下面的例子会变得很简单,很多东西都是举一反三,稍稍有些不同的内容,好了,闲话少说,开始这次的学习. ...
- iOS UIKit:viewController之定义(2)
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- iOS UIKit:viewController之层次结构(1)
ViewController是iOS应用程序中重要的部分,是应用程序数据和视图之间的重要桥梁.且应用程序至少有一个view controller.每个view controller对象都负责和管理一个 ...
- iOS UIKit:view
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...
- iOS UIKit:TableView之单元格配置(2)
Table View是UITableView类的实例对象,其是使用节(section)来描述信息的一种滚动列表.但与普通的表格不同,tableView只有一行,且只能在垂直方向进行滚动.tableVi ...
- iOS UIKit:TabBar Controller
1 结构剖析 IOS中的标签导航其实是一个UITabBarController对象,其也是一个Container View Controller.UITabBarController对象创建和管理了一 ...
随机推荐
- eclipse中配置c++开发环境 Eclipse + CDT + MinGW
转自eclipse中配置c++开发环境 Eclipse + CDT + MinGW 基本框架:Eclipse + CDT + MinGW 背景知识: CDT:CDT 是完全用 Java 实现的开放源码 ...
- LA_3263_That_Nice_Euler_Circuits_(欧拉定理+计算几何基础)
描述 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=15& ...
- POJ_2001_Shortest_Prefixes_(Trie)
描述 http://poj.org/problem?id=2001 给出一组单词,求每个单词的最小唯一前缀. 最小唯一前缀:该前缀不能是其他单词的前缀,并且最小,如果不存在,则为该单词本身. Shor ...
- 在Azure中使用Load Runner测试TCP最大并发连接数
对于Azure中的每一台虚机,它所能支持的TCP最大并发连接数是50万(参考微软官网: http://azure.microsoft.com/en-us/documentation/articles/ ...
- tomcat6 配置SSI 支持.shtml文件
一.修改tomcat-6.0.36\conf\server.xml 文件: 把文件里 ssi 相关的 servlet .servlet-mapping .filter .filter-mapping注 ...
- 全面理解Unity加载和内存管理
全面理解Unity加载和内存管理http://game.ceeger.com/forum/read.php?tid=4394&fid=2&uid=6507 1.用简单的“for”循环 ...
- 【转】Android中设置TextView的颜色setTextColor--代码中设置字体颜色
原文网址:http://www.cnblogs.com/myphoebe/archive/2012/01/06/2314728.html android中设置TextView的颜色有方法setText ...
- Hadoop RCFile存储格式详解(源码分析、代码示例)
RCFile RCFile全称Record Columnar File,列式记录文件,是一种类似于SequenceFile的键值对(Key/Value Pairs)数据文件. 关键词:Reco ...
- 浅析五大ASP.NET数据控件
转自:http://kb.cnblogs.com/page/69207/ 摘要:ASP.NET中有不少的控件,在这当中有一部分是用来处理数据的控件.在这里我们正要讨论的就是ASP.NET数据控件,希望 ...
- [PeterDLax著泛函分析习题参考解答]第1章 线性空间
1. 证明定理 1. 2. 验证上述结论. 3. 证明定理 3. 4. 证明定理 4. 证明: 由 $$\bex x=\sum_{k=1}^{n-1}a_k\cdot \sum_{j=1}^{n-1} ...