zoukankan      html  css  js  c++  java
  • iOS 再谈 代理传值,block反向传值

    本贴的例子是:有A和B两个界面,要实现的效果就是先让A跳转到B,然后B中有个颜色的参数,当B跳转到A时,把这个颜色的参数传递给A,在A中利用这个颜色改变自己界面的颜色。

    第1步:在发送者(界面B)中,制定协议(在.h头文件中声明)
    // 协议名一般以本类的类名开头+Delegate (包含前缀)
     @protocol ConfigViewControllerDelegate <NSObject>
    // 声明协议方法,一般以类名开头(不需要前缀)
    - (void)changeBgColor:(UIColor *)color;

    B 是委托 1定义协议, 2声明代理, 3调用协议。
    第2步:在发送者(界面B)中的.h文件中代理协议。    传出类-- 声明代理。  
    @interface ConfigViewController : UIViewController
    // id即表示谁都可以设置成为我的代理
    @property (nonatomic,weak) id<ConfigViewControllerDelegate> delegate;
     // ARC使用weak,MRC使用assign
    @end
    
    第3步:在发送者(界面B)中的方法中通知代理(最重要的步骤
      //这一步一般是在B跳转到A的方法中实现的,我是在B中创建了一个Button,让这个通知代理在Button中跳转方法中实现。 
     if ([self.delegate respondsToSelector:@selector(changeBgColor:)]) { 
        // 加入if语句就是先判断在界面A中是否有changeBgColor这个方法,当有这个方法的时候,才进行代理传值。
        //一般会先实例化出一个color的对象,在进行代理传值的时候,是带着这个color一起传递过去的。
        [self.delegate changeBgColor:color];
      //这里的self是界面B,self.delegate就是界面A了 调用(在第4步和第5步的设置中设置了)
    }

    A  1遵循协议    2设置代理    3实现协议        传入类  ---- 代理类
    第4步:在接收者(界面A)中遵守协议。
      @interface ViewController () <ConfigViewControllerDelegate>
    
    第5步:在接收者(界面A)中设置自己成为代理。
      ConfigViewController *testVC = [[ConfigViewController alloc] init];
      testVC.delegate = self;
    
    第6步:在接受者(界面A)中实现协议中的方法。
      - (void)changeBgColor:(UIColor *)color{
      self.view.backgroundColor = color;
      }

    //////------block

    iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值)

            使用Block的地方很多,其中传值只是其中的一小部分,下面介绍Block在两个界面之间的传值:

            先说一下思想:

            首先,创建两个视图控制器,在第一个视图控制器中创建一个UILabel和一个UIButton,其中UILabel是为了显示第二个视图控制器传过来的字符串,UIButton是为了push到第二个界面。

            第二个界面的只有一个UITextField,是为了输入文字,当输入文字,并且返回第一个界面的时候,当第二个视图将要消失的时候,就将第二个界面上TextFiled中的文字传给第一个界面,并且显示在UILabel上。

    其实核心代码就几行代码:

    下面是主要代码:(因为我是用storyBoard创建的工程,所以上面的属性和相应的方法,是使用系统生成的outlet)

    一、在第二个视图控制器的.h文件中定义声明Block属性-----    传出类   --1 声明block, 2调用

    typedef void (^ReturnTextBlock)(NSString *showText);
    
    @interface TextFieldViewController : UIViewController
    
    @property (nonatomic, copy) ReturnTextBlock returnTextBlock;
    
    - (void)returnText:(ReturnTextBlock)block;
    
    @end

            第一行代码是为要声明的Block重新定义了一个名字

        ReturnTextBlock

            这样,下面在使用的时候就会很方便。

            第三行是定义的一个Block属性

            第四行是一个在第一个界面传进来一个Block语句块的函数,不用也可以,不过加上会减少代码的书写量

    二、实现第二个视图控制器的方法

    - (void)returnText:(ReturnTextBlock)block {
      self.returnTextBlock = block;
    }
    - (void)viewWillDisappear:(BOOL)animated {
      
      if (self.returnTextBlock != nil) {
        self.returnTextBlock(self.inputTF.text);
      }
    }

            其中inputTF是视图中的UITextField。

            第一个方法就是定义的那个方法,把传进来的Block语句块保存到本类的实例变量returnTextBlock(.h中定义的属性)中,然后寻找一个时机调用,而这个时机就是上面说到的,当视图将要消失的时候,需要重写:

    - (void)viewWillDisappear:(BOOL)animated;

    方法。

    三、在第一个视图中获得第二个视图控制器,并且用第二个视图控制器来调用定义的属性 --- 传入类 --   3 回调  实现block 

    如下方法中书写:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
      // Get the new view controller using [segue destinationViewController].
      // Pass the selected object to the new view controller.
      TextFieldViewController *tfVC = segue.destinationViewController;
      
      [tfVC returnText:^(NSString *showText) {
        self.showLabel.text = showText;
      }];
    }

         可以看到代码中的注释,系统告诉我们可以用[segue destinationViewController]来获得新的视图控制器,也就是我们说的第二个视图控制器。

            这时候上面(第一步中)定义的那个方法起作用了,如果你写一个[tfVC return Text按回车  ,系统会自动提示出来一个: 

    tfVC returnText:<#^(NSString *showText)block#>

    的东西,我们只要在焦点上回车,就可以快速创建一个代码块了,大家可以试试。这在写代码的时候是非常方便的。

    附件中是完整的工程代码,大家可以运行看看效果

    //////////////-------

    block介绍:http://blog.csdn.net/totogo2010/article/details/7839061

    链接一篇描述block回调挺有意思的文章: http://blog.csdn.net/mobanchengshuang/article/details/11751671

    分析:

    在B试图控制器中,定义一个block,参数为字符串

     
    1.//SecondViewController.h
    2.typedef void (^ablock)(NSString *str);
     
    1.//SecondViewController.h
    2. 
    3.@property (nonatomic, copy) ablock block;

    在B试图控制器中,当输入名字,点击对应的确定按钮后

     
    01.- (IBAction)blockMethod:(id)sender {
    02.if ([self notEmpty]) {
    03.if (self.block) {
    04.self.block(self.nameTextField.text);
    05.[self dismissViewControllerAnimated:YES completion:nil];
    06.}
    07.}else{
    08.[self showAlert];
    09.}
    10.}

    在A试图显示,回调block

     
    1.- (IBAction)showSecondWithBlock:(id)sender {
    2.SecondViewController *second = [[SecondViewController alloc] initWithNibName:@'SecondViewController' bundle:nil];
    3.[self presentViewController:second animated:YES completion:nil];
    4.second.block = ^(NSString *str){
    5.self.nameLabel.text = str;
    6.};
    7.}
  • 相关阅读:
    [杂谈]关于前端如何学习框架的一点牢骚
    【2018】面试复习大纲
    迟来的2017总结
    [转载并收藏]JavaScript 疲劳终极指南:我们行业的真相
    想做好产品,一定要成为自己产品的用户
    2017年个人提升计划
    Chrome新发现
    不要被所在的公司或企业绑架
    半夜不想睡有感
    2016年总结
  • 原文地址:https://www.cnblogs.com/iOS-mt/p/8908580.html
Copyright © 2011-2022 走看看