iOS路由设计(一) 路由响应链方法进行传值

http://www.cocoachina.com/ios/20161205/18282.html


现在有一个需求, 如果一个自定义cell中有一个button, button的点击事件要将自定义cell中的某个属性值传给控制器, 应该怎么做?

当然你可以利用代理, 通知, 和block回调, 除此之外, 还有没有其他办法呢? 有! 那就是今天要说的路由响应链方法.

说到路由响应链, 其实跟路由器的路由半毛钱关系没有. 关键在于响应链, 说到响应链, 就不得不说一下UIResponder

The UIResponder class defines an interface for objects that respond to and handle events. It is the superclass of UIApplication, UIView and its subclasses (which include UIWindow). Instances of these classes are sometimes referred to as responder objects or, simply, responders.

UIResponder类定义了一个对象接口用来响应和处理事件, 它是UIApplication, UIView以及UIView的子类(包括UIWindow)的父类, 这些类的实例对象被称为响应对象或者响应者

然后UIResponder对象有一个重要的属性叫做nextResponder, 下一个响应者. 现在回到我们的需求

2868984-dd54f80d1ac7b083.png

响应者链

当button向controller传值的时候(红色虚线箭头方向), 这是逆传, 大部分情况下我们都使用通知代理和block, 但是nextResponsder这个属性让我们可以直接获取到控件的父类

  • 首先,我为UIResponder建立一个分类

2868984-adb52737c09de0d8.png

UIResponder + Router分类
  • 在分类中, 我实现这样一个方法

1
2
3
4
5
6
7
8
9
10
11
#import "UIResponder+Router.h"
 
@implementation UIResponder (Router)
 
- (void)routerWithEventName:(NSString *)eventName userInfo:(NSDictionary *)userInfo {
     if  (self.nextResponder) {
          [[self nextResponder] routerWithEventName:eventName userInfo:userInfo];
     }
}
 
@end

第一个参数是事件名称, 第二个参数是需要传递的参数信息
看起来这样一个方法会陷入死循环, 其实不然, 当self.nextResponder向上一直找到UIApplication都还不能响应事件的时候, 系统就会自动丢弃这个事件

而当我控制器中重写这个方法的时候, 相当于重写父类方法的时候,那么系统就会走子类的方法, 那么参数就直接传递给控制器了

控制器中重写父类方法

1
2
3
4
5
6
- (void)routerWithEventName:(NSString *)eventName userInfo:(NSDictionary *)userInfo {
     if  ([eventName isEqualToString:YFTransferNameEvent]) {
         NSString * name = userInfo[YFUserName];
         NSLog(@ "用户的姓名为:%@" ,name);
     }
}

cell中Button的点击事件

1
2
3
4
5
- (void)buttonClickAction:(UIButton *)sender {
     [sender routerWithEventName:YFTransferNameEvent userInfo:@{
                                                             YFUserName:[self userName],
                                                             }];
}

也就是说, button将事件处理传递给nextResponder, 也就是cell, cell没有重写父类方法, 继续将事件传递给tableView, tableView也没有重写父类方法, 于是将事件处理传递给控制器的view,控制器的view也没有重写父类方法, 于是将事件处理传递给控制器, 控制器重写了父类方法, 于是就走控制器重写的方法, 进行事件处理, 事件就成功地从button传到了控制器.

2868984-48966cf73e58b34f.png

响应者链传递

实现效果如下图, 我依次点击每一个button,(注意:不是点击cell),就会在控制器里返回出结果, 并赋值给Label

2868984-4385f16c67e4cd1b.gif

实现效果

具体的demo链接附在下面了, 有兴趣的可以看一下, 非常简单的
demo链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值