UINavigationController笔记

3rd,March,2017

概述

UINavigationController继承UIViewController, 是一个特殊的视图控制器,具有层级结构,用于管理一组具有层级结构的视图控制器(通过viewControllers 属性维持这组视图控制器)。UINavigationController维持着视图控制器栈,通过入栈和出栈更改最顶层的视图控制器。viewContoller数组中的第一个视图控制器就是根视图控制器,最后一个就是栈顶的视图控制器,也就是屏幕上显示的视图控制器。
除了视图控制器,UINavigationController还管理着导航栏和可选的工具栏。UINavigationController中的属性UINavigationBar管理导航栏栈,而导航栏的更新主要通过导航栏控制器中的视图控制器栈中的每一个视图控制器相关联的类型为UINavigationBarItem的navigationBarItem属性进行配置。这里navigationBar之于navigationBarItem有点像UINavigationController之于UIViewController。要注意的是UINavigationBarItem是继承NSObject,UINavigationBar是继承UIView。
导航栏控制器也提供相应的代理去协调管理行为。
具体组成可以看这张来自苹果官网文档的图片:
UINavigationController笔记_第1张图片

导航栏

UINavigationBar中有items属性(类型为[UINavigationItem]?),维持整个导航栏控制器的导航栏栈。而界面上显示的也是栈顶的UINavigationItem。界面元素如下图所示(图片来自苹果官方文档):
左边按钮:如果新的栈顶控制器中设置了导航Item的leftBarButtonItem属性,则显示该样式,如果没有自定义的leftBarButtonItem属性,则显示backBarButtonItem属性内容(根控制器的navigationItem的backBarButtonItem属性没有默认的值,并且也无法设值,尝试了下设置,但无法显示。 而非根视图控制器则会自动创建默认的backBarButtonItem。)
中间标题:导航栏中间则是标题视图,可以通过设置titleView进行定制视图,或者通过title属性直接设置文本内容。
右边按钮:通过rightBarButtonItem进行配置。
Prompt: 在中间标题上面还可以通过prompt属性进行配置。当设置该属性后,导航栏高度会增加30px,默认导航栏高度为44
UINavigationController笔记_第2张图片
补充: 通过navigationBar的tintColor属性可以设置导航栏按钮的线条颜色,通过barTintColor则可以设置导航栏的背景色。

tintColor VS barTintColor

tintColor表示导航栏上按钮(UINavigationBarItem与barButtonItems)的线条颜色。barTintColor则是代表导航栏背景颜色。

导航栏背景色: barTintColor VS backgroundColor

虽然navigationBar继承UIView, backgroundColor也可以设置背景颜色。但navigationBar中设置backgroundColor并没有效果,需通过barTintColor才可以设置导航栏的背景颜色。
iOS7开始给UIView添加了tintcolor属性,该属性会影响整个视图层级结构,也就是具备传递性。tintColor值默认为nil,当值为nil时为系统蓝色,tintAdjustMode默认为UIViewTintAdjustmentModeNormal。这两个属性改变时,会出发view 以及subview的tintColorDidChange方法。而backgroundColor不具备传递性。

常用设置

颜色设置

// 设置导航栏按钮颜色
self.navigationBar.tintColor = UIColor.white
// 设置导航栏背景颜色
self.navigationBar.barTintColor = UIColor.blue
// 设置导航栏title颜色
[self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName: UIColorFromRGB(0xECECED)}]

设置导航栏标题

// m1 在UIViewController中设置title属性
self.title = “标题"
// m2 在UIviewController中设置navigationItem的title属性
self.navigationItem.title = "标题"
// m3 在UINavigationController中设置,但该方法只能设置根Viewcontroller的标题
self.navigationBar.topItem?.title = “标题”

设置根控制器

// m1: 通过实例方法init(rootViewController:)
let navigationController = UINavigationController.init(rootViewController: MessageBoxViewController())
// m2: 在UINavigation子类中设置viewControllers数组
self.viewControllers = [MessageBoxViewController()]

隐藏导航栏

[self.navigationController setNavigationBarHidden:YES animated:YES];

跳转时隐藏底部tabBar

A->B,应该在A页面跳转部分设置,

// A.swift
let vc = B()
vc.hidesBottomBarWhenPushed = true
self.navigationController?.pushViewController(vc, animated: true)

设置导航栏按钮

30th,August,2016

// 1. 初始化按钮
// 图标
let iconItem = UIBarButtonItem(image: UIImage.init(named: "milk"), style: .plain, target: self, action: #selector(rightBarItemAction))
// 文本
let labelItem = UIBarButtonItem(title: "下一步", style: .plain, target: self, action: #selector(rightBarItemAction))
// 2. 设置按钮
// 设置左边按钮
self.navigationItem.leftBarButtonItem = iconItem
// 设置返回按钮
self.navigationItem.leftBarButtonItem = iconItem
// 设置右边按钮
self.navigationItem.rightBarButtonItem = iconItem

注意事项

导航页面与内容页面重叠

从iOS7开始,内容页面会与导航栏部分重叠。因而在设计viewController的内容时必须考虑这个空白。ps: 也就是导航栏(44)跟状态栏(20),会遮挡ViewController中的区域。

问题列表

【?】设置返回按钮时,不知道为什么并没有生效,还是系统默认的返回按钮。
【?】这里有一个疑问,在设置isTranslucent属性为false后,则并不存在这种重叠情况,而官方文档中并没有指出设置该属性会有该作用。

参考资料

苹果官方文档–UINavigationController
苹果官方文档–UINavigationBar
UINavigationItem UINavigationBar 关系分析
CodePath–Navigation Controller
【iOS】让我们一次性解决导航栏的所有问题

你可能感兴趣的:(iOS之UI模块)