IOS笔记047-代理传值和block传值

摘要:
编辑联系人界面的数据传递使用block实现。回到顶部2、代理传值数据传递方向是从add控制器传递到contact控制器。

阅读目录

在两个不同的控制器之间传递数据,可以使用代理传值或者block传值。

例子是一个简单通讯录。

主界面如下:

屏幕快照 2015 06 13 13 05 15

添加联系人界面

屏幕快照 2015 06 13 13 05 08

查看/编辑联系人界面:默认是查看模式,点击编辑后进入编辑模式

屏幕快照 2015 06 13 13 05 23

编辑模式

屏幕快照 2015 06 13 13 05 36

数据更新成功。

屏幕快照 2015 06 13 13 05 44

其中添加联系人界面的数据传递使用代理方式实现。

编辑联系人界面的数据传递使用block实现。

下面来看具体过程

回到顶部

1、整个界面搭建

屏幕快照 2015 06 13 13 32 34

在storyboard里拖拽四个控制器,其中联系人界面是一个UITableView。界面之间的跳转使用代码实现,但是要给每一个控制器指定一个标识。按功能分别指定为login,contact,add,edit.

屏幕快照 2015 06 13 13 25 46屏幕快照 2015 06 13 13 37 10

具体细节我就不说了,关键是代理传值的实现。

回到顶部

2、代理传值

数据传递方向是从add控制器传递到contact控制器。至于为什么使用代理,主要是为了降低类之间的耦合度。

回到顶部

1、这里需要给add控制器添加一个代理对象,然后定义一个代理需要遵守的协议。

// 代理实现逆传数据

@classSLQContact; // 模型对象

@classSLQAddViewController; //

@protocol SLQAddViewControllerDelegate<NSObject>

@optional

// 代理方法

- (void)addViewController:(SLQAddViewController *)addVC DidClickBtnWithContact:(SLQContact *)contact;

@end

@interface SLQAddViewController : UIViewController

/*代理对象*/

@property(strong, nonatomic) id<SLQAddViewControllerDelegate> delegate;

@end

2、等需要传递数据时只需通知代理一声即可,不需要关心代理如何做。

在添加联系人界面里点击添加按钮后就去通知代理传递数据。

// 添加联系人按钮,单击后传递数据到联系人控制器,并返回上一个界面

- (IBAction)addBtn:(id)sender {

//传递模型数据

SLQContact*temp = [SLQContactcontactWithName:_nameField.textandPhone:_phoneField.text];

// 通知代理

if([_delegate respondsToSelector:@selector(addViewController:DidClickBtnWithContact:)])

{

[_delegateaddViewController:selfDidClickBtnWithContact:temp];

}

// 返回上一个界面

[self.navigationControllerpopViewControllerAnimated:YES];

}

回到顶部

3、还有最关键的一步,那就是指定代理对象是谁

这里指定代理对象的是contact控制器,因为,要把数据传递给它,所以它作为接收者也就是代理方。

// 添加按钮,按下后进入添加联系人界面

- (IBAction)addBtn:(id)sender {

//

// [self performSegueWithIdentifier:@"contactToAdd" sender:nil];

// 通过代码获取storyboard中得控制器

UIStoryboard *story = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

// 获取main。storyboard中得控制器,以标识符区分

SLQAddViewController* addVC = [story instantiateViewControllerWithIdentifier:@"add"];

// 代理逆传数据

//如果通过代码跳转的话,必须知道目的控制器,整个程序中也只有这个时候才知道下一个控制器是谁,所以在这里指定代理对象为contact控制器再好不过了

addVC.delegate = self;

// 跳转到添加联系人界面 [self.navigationController pushViewController:addVC animated:YES];

}

// 实现代理方法,记得让类遵守协议

- (void)addViewController:(SLQAddViewController *)addVC DidClickBtnWithContact:(SLQContact *)contact

{

// 添加数据到数组

[_contacts addObject:contact];

// 刷洗表格

[self.tableView reloadData];

}

2、block传值

1、在编辑控制器中对block进行生声明以及定义

// blocl传值使用

@classSLQContact;

// 声明block别名,参数为要传递的数据。

typedef void(^SLQEditViewControllerBolok)(SLQContact *);

@interface SLQEditViewController : UIViewController

/*模型*/

@property(strong, nonatomic) SLQContact*contact;

/*block 对象*/

@property(strong, nonatomic) SLQEditViewControllerBolokblock;

@end

回到顶部

2、在点击保存按钮后进行数据传递

// 保存按钮事件

- (IBAction)save:(id)sender

{

// 传递模型数据

SLQContact*contact = [SLQContactcontactWithName:_nameField.textandPhone:_phoneField.text];

// block实现传值,先检查是否有数据,如果有传递模型数据

if(_block)

{

_block(contact);

}

// 回到上个界面

[self.navigationControllerpopViewControllerAnimated:YES];

}

回到顶部

3、关键一点还是要在数据接收方也就是contact控制器中对block内容进行包装

因为要通过代码跳转,同样需要知道目的控制器,跳转的地方就是选中cell的时候。

// 选中cell后进入编辑界面

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

// 获取编辑控制器

UIStoryboard *story = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

// 获取目的控制器

SLQEditViewController*editVC = [story instantiateViewControllerWithIdentifier:@"edit"];

// 传递模型数据到edit控制器(这是一种顺序传值)

editVC.contact = self.contacts[indexPath.row];

// 使用block包装之后要进行的操作

editVC.block = ^(SLQContact *contact){

// 修改数据

[self.contacts replaceObjectAtIndex:indexPath.row withObject:contact];

// 刷新表格

[self.tableView reloadData];

};

// 跳转到编辑界面

[self.navigationControllerpushViewController:editVC animated:YES];

}

回到顶部

3、顺序传值

顺序传递数据比价简单,只需要接收方有一个属性对要传递的数据进行接收就行。

上面在进入编辑控制界面时就要对数据进行传递,要把在联系人界面的数据传递到编辑控制器界面,然后对其进行修改。

//选中cell后进入编辑界面

- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath

{

//获取编辑控制器

UIStoryboard*story = [UIStoryboardstoryboardWithName:@"Main"bundle:nil];

//获取目的控制器

SLQEditViewController*editVC = [storyinstantiateViewControllerWithIdentifier:@"edit"];

//传递模型数据到edit控制器(这是一种顺序传值)

editVC.contact=self.contacts[indexPath.row];

//使用block包装之后要进行的操作

editVC.block= ^(SLQContact*contact){

//修改数据

[self.contactsreplaceObjectAtIndex:indexPath.rowwithObject:contact];

//刷新表格

[self.tableViewreloadData];

};

//跳转到编辑界面

[self.navigationControllerpushViewController:editVCanimated:YES];

}

上面的代码这样写。是因为在编辑控制器中已经定义了一个模型对象接收传递的数据。

@interface SLQEditViewController : UIViewController

/*模型对象,接收传递过来的数据*/

@property(strong, nonatomic) SLQContact*contact;

/*block 对象*/

@property(strong, nonatomic) SLQEditViewControllerBolokblock;

@end

同样传递的地方也是在控制器跳转之前进行数据的传递。

回到顶部

4、总结

传值的方是由到导航控制器的行走方向决定的。

顺序传值:

由源控制器传递当目的控制器。

接收方有一个属性接收传递数据,在控制器跳转之前进行传递

逆序传值:

由源控制器传递当目的控制器。

代理:

在发送方对声明代理对象,然后定义代理协议,要传递的数据要放在代理方法的参数中,最后在触发事件后通知代理

在接收方设置代理位接收方,实现代理方法

block:

在发送方对声明block,要传递的数据要放在block的参数中,最后在触发事件后调用block

在接收方设置block的内容

免责声明:文章转载自《IOS笔记047-代理传值和block传值》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CentOS 7 下编译安装lnmp之PHP篇详解使用Dockerfile制作镜像下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

domino控制台命令

Broadcast message 向该服务器的用户广播消息 Broadcast message usernames 向该服务器的某一用户广播消息 Dbcache Flush 关闭当前在数据库高速缓存中打开的所有数据库。使用此命令可以在高速缓存中维护数据库,例如:备份或恢复数据库。 Drop username 关闭一个或多个服务器会话。如果...

设计模式之动态代理

在了解什么是动态代理模式,以及怎么实现动态代理模式之前,我们先明确一个场景,那就是当我们需要对一类实现类增加一些额外处理对其中的某些方法做一些增强时。譬如增加日志打印,参数校验,鉴权等。这些功能很重要,但是又具有一定的独立性(与业务代码不相关)。针对这种情况, 我们就可以采用动态代理模式来实现。 动态代理顾名思义,就是动态的对方法实现代理。要真正理解动态代...

第18章-使用WebSocket和STOMP实现消息功能

Spring 4.0为WebSocket通信提供了支持,包括: 发送和接收消息的低层级API; 发送和接收消息的高级API; 用来发送消息的模板; 支持SockJS,用来解决浏览器端、服务器以及代理不支持WebSocket的问题。 1 使用Spring的低层级WebSocket API 按照其最简单的形式,WebSocket只是两个应用之间通信的通道。...

【java项目实战】代理模式(Proxy Pattern),静态代理 VS 动态代理

这篇博文,我们主要以类图和代码的形式来对照学习一下静态代理和动态代理。重点解析各自的优缺点。 定义 代理模式(Proxy Pattern)是对象的结构型模式,代理模式给某一个对象提供了一个代理对象,并由代理对象控制对原对象的引用。 代理模式不会改变原来的接口和行为,仅仅是转由代理干某件事,代理能够控制原来的目标,比如:代理商,代理商仅仅会买东西,但并不会...

SqlServer数据库主从同步

分发/订阅模式实现SqlServer主从同步 在文章开始之前,我们先了解一下几个关键的概念: 分发服务器分发服务器是负责存储在同步过程中所用复制信息的服务器。可以比喻成报刊发行商。 分发数据库分发数据库用于存储发布数据库所做的更改。它还可以存储快照和合并发布的历史信息。存在于系统数据库中,默认为destribution. 发布服务器使服务器能够成为发布...

【Mybatis进阶】动态代理

如果你想更深刻的理解Mybatis动态代理的原理,那么你应该先知道 什么是代理模式? 在没有动态代理的时候Mybatis是如何实现dao层的? 什么是代理模式 具体可以阅读笔者的博客—— 代理模式 在没有动态代理的时候Mybatis是如何实现dao层的 本篇博客基于mybatis的环境已经搭建完成,如果不知道如何搭建,具体可以阅读笔者的博客——【从零开...