UIStoryboardSegue讲解.
什么是Segue
Storyboard上每一根用来界面跳转的线,都是一个UIStoryboardSegue
对象(简称Segue
)
1 | #import <Foundation/Foundation.h> |
Segue的属性
每一个Segue对象,都有3个属性
@property (nonatomic, readonly) NSString *identifier; // 唯一标识
@property (nonatomic, readonly) id sourceViewController; // 来源控制器
- @property (nonatomic, readonly) id destinationViewController; // 目标控制器
Segue的类型
根据Segue
的执行(跳转)时刻,Segue可以分为2大类型
- 自动型:点击某个控件后(比如按钮),自动执行
Segue
,自动完成界面跳转
设置方法:按住Control键,直接从控件(某个继承UIControl
的控件)拖线到目标控制器.
一般来说,如果点击某个控件后,不需要做任何判断,一定要跳转到下一个界面,建议使用“自动型
Segue
”
- 手动型:需要通过写代码手动执行Segue,才能完成界面跳转
设置方法:
- 按住Control键,从来源控制器(当前控制器)拖线到目标控制器.
- 在Storyboard的Segue属性中设置唯一标识(一般来说命名建议为:”login2index”,既 当前控制器名称+2+目标控制器名称)
- 在适当的时候调用下面方法,来实现跳转.(适当的时候一般是设置控件时,或某些自动跳转)
1 | - (void)performSegueWithIdentifier:(NSString *)identifier |
一般来说,如果点击某个控件后,需要做一些判断,也就是说:满足一定条件后才跳转到下一个界面,建议使用“手动型Segue”(比如用户登录,比如选择后等等)
performSegueWithIdentifier:sender: 方法完整执行过程
总得来说这个方法可以分为三个大的部分:
- 1.根据
identifier
去storyboard
中找到对应的线,新建UIStoryboardSegue
对象
1 | - (instancetype)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination; // Designated initializer |
其实就是执行了这样一句,并且identifier
就是在Storyboard
中Segue
属性设置的标识. 来源就是连线的头部. 目标就是连线尾部.
- 2.调用
sourceViewController
的下面方法,做一些跳转前的准备工作并且传入创建好的Segue对象- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
所谓跳转前的准备,因为可以拿到Segue(来源控制器,目标控制器),所以就可以在这里给下一个控制器传递数据.
注意的是:只能只能由来源控制器调用,来拿到目标控制器.
并且,这个sender
是当初performSegueWithIdentifier:sender:
中传入的sender
.
另外需要注意的是:
- 这个方法是系统默认调用,所以只需要实现即可.
- 凡是
performSegue
都会来到这个方法.所以一般需要对Segue的标识进行判断.于是有了如下的两种固定格式:
1 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender |
1 | #import "IndexTableViewController.h" |
区别:第一种需要在设置标识的值,并且匹配. 第二种却是通过目标控制器判断
个人建议:使用第二种(既可以不在
Storyboard
输入标识,并且因为不涉及字符串,不容易出错.)一个页面的跳转可能不止一个.并且为了后期的可维护性,建议加上标识判断.
- 调用
Segue
对象的- (void)perform;
方法开始执行界面跳转操作
其实就是封装了Push
方法:1.首先取得sourceViewController
所在的UINavigationController
. 2.然后调用UINavigationController
的push
方法将destinationViewController
压入栈中,完成跳转.
但是如果类型是Modal
,就是调用了SourceViewController
的presentViewController
方法将destinationViewController展示出来.
控制器之间的数据传递
根据segue
我们可以吧控制器之间的数据传递分为两种情况:1.顺传 2.逆传
顺,逆关系由Segue
决定
顺传:可以在prepareForSegue:sender:
方法中根据segue参数取得目标控制器,直接给目标控制器传递数据模型.
逆传:只能让源控制器成为目标控制器的代理,然后通过代理方法传递数据.(采用解耦方法)
传递模型的好处是:假如一个数据需要顺传到目标控制器,并且目标控制需要对数据进行了修改,这个时候修改的其实就是数据模型.(所以再次逆传的时候,可以不传数据).