博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 再谈 代理传值,block反向传值
阅读量:5031 次
发布时间:2019-06-12

本文共 4010 字,大约阅读时间需要 13 分钟。

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

第1步:在发送者(界面B)中,制定协议(在.h头文件中声明)
// 协议名一般以本类的类名开头+Delegate (包含前缀) @protocol ConfigViewControllerDelegate 
// 声明协议方法,一般以类名开头(不需要前缀) - (void)changeBgColor:(UIColor *)color; B 是委托 1定义协议, 2声明代理, 3调用协议。
第2步:在发送者(界面B)中的.h文件中代理协议。    传出类-- 声明代理。  
@interface ConfigViewController : UIViewController// id即表示谁都可以设置成为我的代理 @property (nonatomic,weak) id
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 () 
第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.
}

转载于:https://www.cnblogs.com/iOS-mt/p/8908580.html

你可能感兴趣的文章
mysql中把一个表的数据批量导入另一个表中
查看>>
Spring MVC的多视图解析器配置及与Freemarker的集成
查看>>
20160930
查看>>
mpvue学习笔记
查看>>
[App Store Connect帮助]六、测试 Beta 版本(4.3) 管理 Beta 版构建版本:为 Beta 版构建版本提供出口合规证明...
查看>>
[Swift-2019力扣杯春季初赛]2. 校园自行车分配
查看>>
SQL SERVER将远程服务器的数据库备份到本地文件夹
查看>>
[LeetCode] 628. Maximum Product of Three Numbers_Easy
查看>>
[Java in NetBeans] Lesson 06. Custom classes
查看>>
[AngularFire2 & Firestore] Example for collection and doc
查看>>
[Javascript] The "this" keyword
查看>>
ElasticSearch-5.3.1集群环境搭建,安装ElasticSearch-head插件,安装错误解决
查看>>
sharepoint Report使用共享数据源部署报错
查看>>
C++ Primer 5th 第16章 模板与泛型编程
查看>>
22个Web 在线编辑器[转]
查看>>
解决“The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path”问题...
查看>>
linux下挂盘
查看>>
【DeepLearning】优化算法:SGD、GD、mini-batch GD、Moment、RMSprob、Adam
查看>>
二维数组
查看>>
spring ioc原理
查看>>