一、继承关系
NSObject->UIResponder->UIViewController->UINavigationController
二、UIViewController相关的属性配置
说明:
下面三个属性,都是针对view controller的父控制器是navigation controller的情景
1、如果view controller加入到navigation controller,那么属性navigationItem标示navigation controller的 navigation bar(导航栏)
var navigationItem: UINavigationItem { get }
2、指示当view controller放入到navigation controller中的时候是否屏幕下边的toolBar(工具栏)是否隐藏
var hidesBottomBarWhenPushed: Bool
3、设置tootBar(工具栏)显示的选项
func setToolbarItems(_ toolbarItems: [UIBarButtonItem]?, animated animated: Bool)
var toolbarItems: [UIBarButtonItem]?
4、返回view controlelr所属的navigation controller
var navigationController: UINavigationController? { get }
三、概述
UINavigationController用来管理多个具有层级关系的视图控制器,用于实现特定的导航跳转功能。
四、图示
settings 导航界面:除了root view(根视图),导航控制器提供了一个返回按钮用于返回上级界面
五、工作原理
UINavigationController通过栈的方式管理控制器,通过入栈和出栈来展示视图控制器。
栈是一个view controllers数组,数组的第一个元素为 root view controller(根视图控制器),最后一个元素为当前展示的view controller。可通过segues 或此类的方法添加或删除视图控制器。
六、UINavigationController管理的两个重要组件
引用官方说明
导航控制器管理导航栏(navigationBar)和可选导航工具栏(toolBar)的创建、配置和显示。允许自定义导航栏的外观相关属性,但您必须不更改其frame、bounds、或αlpha值。如果你的子类化UINavigationBar,必须用initWithNavigationBarClass:toolbarClass: 初始化navigation controller。
显示或隐藏navigationBar用属性 navigationBarHidden或者方法setNavigationBarHidden:animated:
导航栏控制器navigation bar的内容通过navigation stack中view controllers相关联的navigation item对象(UINavigationItem类)动态创建的。
1、navigationBar(顶部导航栏)
var navigationBar: UINavigationBar { get }
显示隐藏navigationBar
//以动画方式
func setNavigationBarHidden(_ hidden: Bool, animated animated: Bool)self.navigationController.setNavigationBarHidden(true, true)
//静态实现
var navigationBarHidden: Boolself.navigationController.navigationBarHidden = true
//通过手势或布局实现
var hidesBarsWhenVerticallyCompact: Bool
var hidesBarsWhenKeyboardAppears: Bool
..更多参考
2、toolBar(可选的底部工具栏)
var toolbar: UIToolbar! { get }
navigationController自带了一个工具栏,默认是不显示的,通过设置self.navigationController.toolbarHidden = false 来显示工具栏,工具栏中的内容可以通过viewController的toolbarItems来设置,显示的顺序和设置的Array中存放的顺序一致,其中每一个数据都一个UIBarButtonItem对象,可以使用系统提供的很多常用风格的对象,也可以根据需求进行自定义。
显示隐藏toolBar
//以动画方式
func setToolbarHidden(_ hidden: Bool,animated animated: Bool)self.navigationController.setToolbarHidden(true, true)
//静态实现
var toolbarHidden: Boolself.navigationController.navigationBarHidden = true
例如下面:
class TwoViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//配置工具栏的选项卡按钮风格
let configArr:Array<UIBarButtonSystemItem> = [.Add, .Bookmarks, .Camera, .Cancel, UIBarButtonSystemItem.Compose, .Done, .Edit, .Search, .Stop, .Trash, .Undo, .Rewind, .Reply, .Refresh, .Redo]
//创建toolbarItems
self.toolbarItems = []
//创建选项卡按钮
for var i = 0; i < configArr.count; i++ {
let btn = UIBarButtonItem(barButtonSystemItem: configArr[i], target: self, action: "clickHandler")
self.toolbarItems?.append(btn)
}
}
}
效果图如下
七、更新navigationBar
navigationBar有几个部分组成,分别是leftBarButtonItem, titleView ,rightBarButtonItem,backBarButtonItem
1、Left side of the navigationBar
a)如果当前的viewController设置了leftBarButtonItem,则显示当前VC所自带的leftBarButtonItem。
b)如果当前的viewController没有设置leftBarButtonItem,且当前VC不是rootVC的时候,则显示前一>层VC的backBarButtonItem。如果前一层的VC没有显示的指定backBarButtonItem的话,系统将会根据>前一层VC的title属性自动生成一个back按钮,并显示出来。
c)如果当前的viewController没有设置leftBarButtonItem,且当前VC已是rootVC的时候,左边将不显示任何东西。
2、title部分
a)如果当前VC通过
.navigationItem.titleView指定了自定义的titleView,系统将会显示指定的titleView,此处要注意自定>义titleView的高度不要超过navigationBar的高度,否则会显示出界。b)如果当前VC没有指定titleView,系统则会根据当前VC的title或者当前VC的navigationItem.title的内容创建一个UILabel并显示,其中如果指定了navigationItem.title的话,则优先显示navigationItem.title的内容。
3、Right side of the navigationBar
a)如果当前VC指定了rightBarButtonItem的话,则显示指定的内容。
b)如果当前VC没有指定rightBarButtonItem的话,则不显示任何东西。
八、操作视图控制器
navigation controller是通过stack的方式管理 view controller的,在工作原理章节有介绍…
几个重要方法
1、把指定的view controller放入到栈中
func pushViewController(_ viewController: UIViewController,animated animated: Bool)
2、把栈中顶部的view controller移除
func popViewControllerAnimated(_ animated: Bool) -> UIViewController?
3、跳转到根控制器:
移除除了root viewController的所有元素,更新并显示 root viewController,返回移除的元素。
func popToRootViewControllerAnimated(_ animated: Bool) -> [UIViewController]?
4、跳转到指定的控制器:
把参数中viewController推入栈顶,移除之前在viewController之上面的元素,返回移除的元素。
func popToViewController(_ viewController: UIViewController,
animated animated: Bool) -> [UIViewController]?
5、ios7 手势返回功能:
navigationController添加这个手势到它的view上用来移除栈中最顶端的view controller
var interactivePopGestureRecognizer: UIGestureRecognizer? { get }
//开启这个功能
self.navigationController.interactivePopGestureRecognizer.enabled = true
6、已模态方式展示viewController,同样会把vc压入栈
func showViewController(_ vc: UIViewController, sender sender: AnyObject?)
参数: vc:要展示的vc sender: 展示vc的请求者
九、delegate
可以使用导航代理来执行响应于导航界面中的更改的其他操作。
主要用到的方法如下:
optional func navigationController(_ navigationController: UINavigationController,
didShowViewController viewController: UIViewController,
animated animated: Bool){
//显示vc后执行的操作
}
optional func navigationController(_ navigationController: UINavigationController,
willShowViewController viewController: UIViewController,
animated animated: Bool){
//将要显示vc执行的操作
}