前言:
当我们需要多个View Controller来完成多个界面时,经常会需要互相传递数据,这时我们就会用到segue。当然delegate也可以胜任这个任务,但是相比delegate,segue的使用就简单很多了。
第四周一个简单的小作业:
制作四步注册界面:
- 用户名/密码
- email / 全名
- 界面上要提示用户名
- 可返回上一步,应能显示之前填写的资料
- 如果返回过上一步,再进来,之前填写过的资料要有
- 确认填写的信息是否正确,
- 显示所有填写过的信息,密码用 * 代替
- 可返回上一步,应能显示之前填写的资料
- 创建成功提示
- 要提到用户名
- 放一个注册下一个用户,要能直接跳到第1步
- 如果想加一个主动结束应用的按钮,可调用 exit(0);
我们就以第1、2步为例来说明ViewController之间利用segue进行数据传递的使用方法。
两个ViewController分别为FirstViewController和SecondViewController(以下简称First、Second)
一、UIStoryboardSegue的定义
@interface UIStoryboardSegue : NSObject
- (id)initWithIdentifier:(NSString *)identifier
source:(UIViewController *)source
destination:(UIViewController *)destination;
@property (nonatomic, readonly) NSString *identifier;
@property (nonatomic, readonly) id sourceViewController;
@property (nonatomic, readonly) id destinationViewController;
@end
-
identifier
用来找到segue的标识
-
source & destination
为了区分视图的跳转,可以用上一个、下一个来表示,也可以用源视图、目标视图来表示。 即:sourceViewController 和destinationViewController。 目标视图控制器是指:即将显示(加载)的视图, 而源视图控制器是指:即将被取代的视图控制器。
二、点击First的下一步,将First中的用户名传给Second
- 先在storyboard中将“下一步”与Second连接起来,并将这一步的segue的identifier属性设成to2。
- 这里我们需要用到
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
这个方法,使用segue参数的destinationViewController属性就可以找到下一个ViewController了。 - 仅仅找到是不够的,我们还需要为下一个ViewController赋值,使用
[viewController setValue: forKey: ]
来存储数据。
First类中:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UIViewController* destinationController = [segue destinationViewController];
if ([segue.identifier isEqualToString:@"to2"]) {
[destinationController setValue:self.nameField.text forKey:@"name"];
}
}
Second类.h中:
@interface SecondViewController : UIViewController
@property (strong, nonatomic) NSString* name;
@end
这样我们就可以在Second中直接使用name属性来访问数据了。
三、点击Second上一步,将Second数据传给First
为了实现这个要求
如果返回过上一步,再进来,之前填写过的资料要有
我们就需要将这些信息传给First,以便在First下一步的时候可以重新将这些数据传进来。
这里不能再用一个segue再指回去,这样会使得界面每次都重新加载会出现各种问题,所以我们利用Second的exit返回上一步,使用unwind segue。同样,这里我们先把unwind segue的identifier属性设成from2To1。
First类.h中:
@interface ViewController : UIViewController
@property (strong, nonatomic) NSString* fullname;
@property (strong, nonatomic) NSString* email;
@end
First类.m中:
- (IBAction)unwindToFirst:(UIStoryboardSegue *)unwindSegue towardsViewController:(UIViewController *)subsequentVC {
// if ([unwindSegue.identifier isEqualToString:@"from2To1"]) {
// NSLog(@"fullname: %@", _fullname);
// }
}
Second类中和之前一样的传值方式:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"from2To1"]) {
UIViewController* destinationController = [segue destinationViewController];
[destinationController setValue:self.fullnameField.text forKey:@"fullname"];
[destinationController setValue:self.emailField.text forKey:@"email"];
}
}
四、其他
-
prepareForSegue: sender:
的触发条件:
当前的视图控制器即将被另一个视图控制器所替代时,segue将处于激活状态,从而调用prepareForSegue:sender: 方法。