反向传值

反向传值

  在开发中我们经常会遇到将当前视图控制中的某些值传到另一个视图控制器,下面将介绍常用的几种反向传值的方法。

下面介绍的是将新用户注册的用户名和密码反向传值到登陆界面

委托实现反向传值

// 实现协议中的方法 让当前视图控制器充当委托(只有遵守协议协议才能充当委托)
- (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文件中,然后在需要的地方取出来即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 声明:本文绝非原创,笔者只是站在巨人的肩膀上总结网络上各位大神的笔记和博客文章,在此向大神们致敬! 在iOS开发过...
    tang_xiaoming阅读 4,936评论 0 12
  • 代理、block、消息中心、单例。 正向传值 通过属性(特性)的值,在上个使用本类(所在类)对象的类中,直接传递其...
    goyohol阅读 876评论 1 5
  • 本文主要讲解iOS中常见的反向传值方法。 1.AppDelegate传值 在AppDelegate中定义相关的属性...
    断剑阅读 5,067评论 15 52
  • 这次主要总结一下界面间的反向传值的主要方法. 1.协议传值 第二个控制器设置协议相关信息第一个控制器实现协议方法 ...
    呼哮山庄阅读 686评论 0 1
  • 原创首发 【龙七七4.1】第一天画画 ——坚持第96天 转眼今天就是画画班的第一天啦,同时也是三期写作班的第一天啦...
    龙七七阅读 523评论 12 6

友情链接更多精彩内容