反向传值
在开发中我们经常会遇到将当前视图控制中的某些值传到另一个视图控制器,下面将介绍常用的几种反向传值的方法。
下面介绍的是将新用户注册的用户名和密码反向传值到登陆界面
委托实现反向传值
// 实现协议中的方法 让当前视图控制器充当委托(只有遵守协议协议才能充当委托)
- (void) fillUsername:(NSString *)username andPassword:(NSString *)password {
UITextField *uidField = (id)[self.view viewWithTag:200];
UITextField *pwdField = (id)[self.view viewWithTag:201];
uidField.text = username;
pwdField.text = password;
}
// 第一个视图控制器中button(注册按钮)的方法
- (void) regButtonClicked:(UIButton *) sender {
GPTwoViewController *twoVC = [[GPTwoViewController alloc] init];
// 为视图控制器绑定委托
twoVC.delegate = self;
// 切换视图控制器的方法1 - 模态切换
// 以模态方式显示指定的视图控制器
[self presentViewController:twoVC animated:YES completion:nil];
}
// 第二个视图控制器中button(填写玩注册信息之后的确定按钮)的方法
- (void) okButtonClicked:(UIButton *) sender {
UITextField *uidField = (id)[self.view viewWithTag:200];
UITextField *pwdField = (id)[self.view viewWithTag:201];
UITextField *emailField = (id)[self.view viewWithTag:203];
// 根据填写的注册信息创建用户对象
GPUser *currentUser = [[GPUser alloc] init];
currentUser.username = uidField.text;
currentUser.password = pwdField.text;
currentUser.email = emailField.text;
if ([[GPUserManager sharedManager] doRegister:currentUser]) {
// 通过协议委托实现反向传值
if (_delegate && [_delegate conformsToProtocol:@protocol(CDFillFormDelegate)]) {
[_delegate fillUsername:currentUser.username andPassword:currentUser.password];
}
// 撤掉模态视图控制器
[self dismissViewControllerAnimated:YES completion:nil];
}
else {
[GPUtility showAlertWithMessage:@"用户名已被注册!" onViewController:self];
}
}
通知实现反向传值
// 第二个视图控制器
- (void) buttonClinked:(UIButton *)sender{
UITextField *textField = (id)[self.view viewWithTag:200];
UITextField *textField1 = (id)[self.view viewWithTag:201];
UITextField *textField2 = (id)[self.view viewWithTag:202];
// 根据填写的注册信息创建用户对象
GPUser *currentUser = [[GPUser alloc] init];
currentUser.username = textField.text;
currentUser.password = textField1.text;
if ([[GPUserManager shardManager] doRegister:currentUser] && [textField1.text isEqualToString:textField2.text]) { // 用户注册成功
// 创建通知对象 第一个参数是通知的名字
// 第二个参数是通知关联的对象 第三个参数通常写nil
NSNotification *note = [[NSNotification alloc] initWithName:@"ABC" object:currentUser userInfo:nil];
// 通过通知中心发送通知
[[NSNotificationCenter defaultCenter] postNotification:note];
[self dismissViewControllerAnimated:YES completion:nil];
}
else{
[GPUtility showAlertWithMessage:@"注册失败" onViewController:self];
}
}
// 第一个视图控制器
- (void) fillTextField:(NSNotification *) sender{
// 从通知中取出关联的对象(注册成功的用户对象)
GPUser *user = sender.object;
UITextField *uidField = (id)[self.view viewWithTag:200];
UITextField *pwdField = (id)[self.view viewWithTag:201];
// 将用户对象的用户名和密码属性分别填入两个文本框
uidField.text = user.username;
pwdField.text = user.password;
}
- (void)viewDidLoad {
// 注册通知的观察者
// 第一个参数:通知的观察者(谁接受通知并作出响应)
// 第二个参数:收到通知后执行的回调方法
// 第三个参数:接收的通知的名字
// 第四个参数:如果写nil表示接收所有对象发出的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fillTextField:) name:@"ABC" object:nil];
}
使用通知后需要销毁 像NSTimer一样
- (void) dealloc{
// 当对象释放的时候 从通知中心移除观察者 避免内存泄露
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
block反向传值
// 第二个视图控制器
// 先定义一个block指针
@class GPUser;
@property (nonatomic, copy) void(^userHandler)(GPUser *);
@end
- (void) buttonClinked:(UIButton *)sender{
UITextField *textField = (id)[self.view viewWithTag:200];
UITextField *textField1 = (id)[self.view viewWithTag:201];
UITextField *textField2 = (id)[self.view viewWithTag:202];
GPUser *currentUser = [[GPUser alloc] init];
currentUser.username = textField.text;
currentUser.password = textField1.text;
if ([[GPUserManager shardManager] doRegister:currentUser] && [textField1.text isEqualToString:textField2.text]) {
if (_userHandler) {
_userHandler(currentUser);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
else{
[GPUtility showAlertWithMessage:@"注册失败" onViewController:self];
}
}
// 第一个视图控制器
- (void) buttonClinked:(UIButton *)sender{
GPSecondViewController *senView = [[GPSecondViewController alloc] init];
// 用输入的用户名和密码创建一个用户对象
UITextField *uidField = (id)[self.view viewWithTag:200];
UITextField *pwdField = (id)[self.view viewWithTag:201];
// 第二个视图控制器希望修改第一个视图控制器的文本框
// 但是第二个视图控制器没有这种能力 所以第一个视图控制器
// 通过第二个视图控制器的block类型的属性传一段代码给它
// 第二个视图控制器通过调用这段代码来实现反向传值
senView.userHandler = ^(GPUser *user){
uidField.text = user.username;
pwdField.text = user.password;
};
[self presentViewController:senView animated:YES completion:nil];
}
除了上面的方法以外,还可以使用单例,当然你也可以使用NSUserDefaults先将数据保存在plist文件中,然后在需要的地方取出来即可。