远书归梦两悠悠,只有空床敌素秋。
阶下青苔与红树,雨中寥落月中愁。
控制器
控制器View的加载
控制器的生命周期
内存警告的时候的整个循环的流程图
控制器常见的创建方式有以下几种
通过storyboard创建
- 先加载storyboard文件(Test是storyboard的文件名)
1 | UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Test" bundle:nil]; |
- 接着初始化storyboard中的控制器
- 初始化“初始控制器”(箭头所指的控制器)
1 | XSViewController *vc = [storyboard instantiateInitialViewController]; |
1 | // 通过一个标识初始化对应的控制器 |
直接创建
1 | XSViewController *XS = [[XSViewController alloc] init]; |
指定xib文件来创建
1 | // 通过Xib创建的控制器 |
- 假设通过Xib创建XSViewController控制器对象
- 如果nibName为nil,首先会去查找
XSView.xib
,如果有,就会去加载XSView.xib
描述的控制器的view - 如果没有找到,就会去找
XSViewController.xib
,如果有,也会去加载 - 都没有找到,就会生成一个空的view
- 空的view是几乎透明的,但不是完全透明的
- 相当于
[UIColor clearColor]
;可以穿透过去,但是完全透明就不能够穿透
- 如果nibName为nil,首先会去查找
- 控制器的view是延迟加载的:用到时再加载UIView(只用于UIViewController或者子控制器)
- 可以用
isViewLoaded
方法判断一个UIViewController的view是否已经被加载 - 控制器的view加载完毕就会调用viewDidLoad方法
- 可以用
UINavigationController
- 为了便于管理控制器,iOS提供了2个比较特殊的控制器
1 | UINavigationController(导航控制器) |
UINavigationController的使用步骤
- 初始化UINavigationController
- 设置UIWindow的rootViewController为UINavigationController
- 根据具体情况,通过push方法添加对应个数的子控制器
UINavigationController的子控制器
- UINavigationController 以
栈
的形式保存子控制器
1 | @property(nonatomic,copy) NSArray *viewControllers; |
控制器出入栈的常用的集中方法
1 | // 使用push方法能将某个控制器压入栈 |
如何修改导航栏的内容
- 显示在我们眼前的永远是栈订控制器
- 导航栏的内容由栈顶控制器的navigationItem属性决定
- 导航控制器是以栈的形式先进后出后进先出(是以数组的形式存储的 数组就是以栈的形式存储的)
- 导航栏返回按钮的文字是由上一个控制器决定的(特例)
UINavigationItem有以下属性影响着导航栏的内容
1 | // 左上角的返回按钮 |
Segue的属性
- 每一个Segue对象,都有3个属性
1 | // 唯一标识 |
Segue的类型
自动型
:点击某个控件后(比如按钮),自动执行Segue,自动完成界面跳转手动型
:需要通过写代码手动执行Segue,才能完成界面跳转
设置导航控制器的导航栏的主题
1 | /** 只会在系统第一次用这类的时候调用(只会调用一次) |
注意点
- 以后看到系统自带的类带有item,就是苹果提供的模型
UINavigationItem
: 设置导航条内容(她不是控件 是模型)UIBarButtonItem
: 设置导航条上按钮的内容 (模型)
UITabBarController
- 跟UINavigationController类似,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型例子就是QQ、微信等应用.
- UITabBarController的使用步骤
- 初始化UITabBarController
- 设置UIWindow的rootViewController为UITabBarController
- 根据具体情况,通过addChildViewController方法添加对应个数的子控制器
UITabBarController添加控制器的方式有2种
1 | - 添加单个子控制器 |
UITabBarController注意点
- 如果UITabBarController有N个子控制器,那么UITabBar内部就会有N个UITabBarButton作为子控件
- UITabBarButton里面显示什么内容,由对应子控制器的tabBarItem属性决定
多控制器管理
segue跳转之前会调用的方法
Modal
- 除了push之外,还有另外一种控制器的切换方式,那就是
Modal
(能用push的尽量用push实现,公司有特殊需求可以用modal) 任何控制器
都能通过Modal的形式展示出来- Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止
1 | // 以Modal的形式展示控制器 |
规律
- modal出谁,谁就能dismiss
- 谁modal,谁也可以dismiss
- dismissViewController 永远移除最后显示的控制器
注意
- 如果一个控制器的View显示到屏幕上,这个控制器一定不能被销毁(要被强引用).
- 谁modal谁就强引用modal出来的控制器
多控制器 管理
UIWindow
1 | loadView、viewDidLoad、viewDidUnload、didReceiveMemoryWarning |
UINavigationController
- 通过非storyboard方式
- 创建导航控制器
- 设置UIWindow的根控制器
- push 1个、2个、3个 子控制器
- 解释push的原理(栈、导航控制器的管理过程)
- 栈底、栈顶控制器的概念
- 如何设置导航栏上面的内容、返回文字的设置
- pop的方法使用
- push和addChild、viewControllers和childViewController的关系
- 通过storyboard方式
多控制器的数据的传递方式(两种):顺传和逆传
顺传
- 控制器的跳转方向: A C
- 数据的传递方向 : A C
- 数据的传递方式 :
- 在A的prepareForSegue:sender:方法中根据segue参数取得destinationViewController, 也就是控制器C,直接给控制器C传递数据(要在C的viewDidLoad方法中取得数据,来赋值给界面上的UI控件)
逆传
- 控制器的跳转方向: A C
- 数据的传递方向 : C A
- 数据的传递方式:
- 让A成为C的代理,在C中调用A的代理方法,通过代理方法的参数传递数据给A