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.h2.typedef void (^ablock)(NSString *str);1.//SecondViewController.h2. 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.}iOS 再谈 代理传值,block反向传值的更多相关文章
- 代理和block反向传值
代理传值: // SendViewController.h #import <UIKit/UIKit.h> @protocol SendInFor <NSObject> -(v ...
- block 反向传值回调
/** * block 反向传值回调 */ //在第二个控制器中 // (1)声明block,在基类中已写好 // (2)写好传值方法 //(1) typedef void (^Return ...
- iOS 代理与block 逆向传值 学习
一般在项目中出现逆向传值的时候就需要用到代理.block 或者通知中心了.由于公司的项目底层封装的很好,所以项目做了三四个月就算碰到需要逆传的情况也不用自己处理.但是最近遇到了一个特别的情况就需要自己 ...
- IOS Block 反向传值
1.在需要像上一个界面传值的.h 文件实现代理方法 @property (nonatomic, copy) void(^isOpenHandler)(BOOL) ; 2.在执行操作的时候需要江操作的结 ...
- 利用协议代理实现导航控制器UINavigationController视图之间的正向传值和反向传值
实验说明 (1)正向传值:比如A类里地值要传给B类用,就是我们先在A类中声明一个B类对象(当然B类头文件要import过来),然后把A类中得某个 值传递给B类中得某个值(所以需要在B类中先准备一个变量 ...
- IOS 学习笔记 2015-04-15 控制器数据反向传值
// // FirstViewController.h // 控制器数据传递 // // Created by wangtouwang on 15/4/15. // Copyright (c) 201 ...
- iOS 页面跳转传值,属性传值,代理传值,代码块传值,单例传值,通知传值
有时候我们在页面跳转的时候回传递相应的参数,如,你想把在第一个页面的文本框里的内容显示在第二个文本框中,或者你又想把第二个文本框中的内容改变之后到第一个页面的文本框中,所有,这个时候我们就要用到页面跳 ...
- iOS Block界面反向传值
在上篇博客 <iOS Block简介> 中,侧重解析了 iOS Block的概念等,本文将侧重于它们在开发中的应用. Block是iOS4.0+ 和Mac OS X 10.6+ 引进的对C ...
- iOS 代理反向传值
在上篇博客 iOS代理协议 中,侧重解析了委托代理协议的概念等,本文将侧重于它们在开发中的应用. 假如我们有一个需求如下:界面A上面有一个button.一个label.从界面A跳转到界面B,在界面B的 ...
随机推荐
- Selenium 的基础框架类
个人写的一个selenium的base类,应该所有使用selenium的同事都会使用到: package com.hx.baserunner; import static java.io.File.s ...
- 【FinancialKnowledge】商业银行业务知识
商业银行业务思维导图 一.资产业务 资产业务是商业银行的主要收入来源 1.放款业务 1.1 信用放款 信用放款,是单凭借款人的信誉, 不需要提供任何抵押品的放款,是一种资本放款. 1.1.1 普通借款 ...
- 奥比中光3D视觉传感器--OpenNI 2配置
PrimeSense是Kinect一代的芯片供应商,位于以色列,也是开源体感开发包OpenNI 的维护者.自从被 Apple 收购后,销声匿迹,OpenNI 也停止更新.现在可以从网站http://s ...
- iOS中判断网络是否联网
#import "AppDelegate.h" #import "ViewController.h" #import "Reachability.h& ...
- 设置span在div中垂直居中
转自:https://blog.csdn.net/weirenkuan/article/details/51177695 使用display:table-cell,span中内容无论多少,都可以垂直居 ...
- Alias Method for Sampling 采样方法
[Alias Method for Sampling]原理 对于处理离散分布的随机变量的取样问题,Alias Method for Sampling 是一种很高效的方式. 在初始好之后,每次取样的复杂 ...
- java.lang.NullPointerException 空指针异常问题
java.lang.NullPointerException 空指针异常问题: 空指针异常抛出的异常信息一般是: Exception in thread "main" java.l ...
- rc522头文件
//本头文件是以51为蓝本 #ifndef __rc522_h__ #define __rc522_h__ #include <string.h> #include <wiringP ...
- windows下如何生成gitlab ssh公钥
1.查看是否已经有了ssh密钥:cd ~/.ssh如果没有密钥则不会有此文件夹,有则备份删除2.生存密钥: $ ssh-keygen -t rsa -C “你的邮箱”按3个回车,密码为空. Your ...
- 【MyBatis】MyBatis之如何存储NULL
如果在sql语句中,不指定jdbcType,那么在存储中遇见null就会发生错误.一般情况下应该在每一个SQL语句的参数中指定jdbcType.比如: #{loginIp,jdbcType=VARCH ...