专栏首页大话swiftRx实现自定义类Delegate

Rx实现自定义类Delegate

事情不多主要是讲讲Rx如何自定义代理,为啥要将这个只要是iOS中太多的delegate 话不多说我们先来代码

Rx方式通过自定义VIew通过代理实现点击获取点击位置


 
@objc
 
protocol MyViewProtocol {
 
 @objc optional   func myTouchBegan(point:CGPoint)
 
}
 


 
 class MyView: UIView {
 
 var delegate: MyViewProtocol?
 


 
 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
 
 super.touchesBegan(touches, with: event)
 
 if delegate != nil {
 


 
 delegate!.myTouchBegan?(point: touches.first!.location(in: self))
 
 }
 
 }
 
}
 

实现Rx扩展

 
extension MyView: HasDelegate {
 
 public typealias Delegate = MyViewProtocol
 
}
 


 
class RxMyViewProxy: DelegateProxy<MyView, MyViewProtocol>, MyViewProtocol, DelegateProxyType {
 


 
 static func setCurrentDelegate(_ delegate: MyViewProtocol?, to object: MyView) {
 
 object.delegate = delegate
 
 }
 
 static func currentDelegate(for object: MyView) -> MyViewProtocol? {
 
 return object.delegate
 
 }
 
 public  weak var myView:MyView?
 
    init(view: MyView) {
 
 self.myView = view
 
 super.init(parentObject: view, delegateProxy: RxMyViewProxy.self)
 
 }
 
 static func registerKnownImplementations() {
 
 self.register {
 
 return RxMyViewProxy(view: $0)
 
 }
 
 }
 
}
 


 
extension Reactive where Base: MyView {
 
 var rxDelegate: RxMyViewProxy {
 
 return RxMyViewProxy.proxy(for: self.base)
 
 }
 
 var touch:ControlEvent<CGPoint>{
 
 let source = self.rxDelegate.methodInvoked(#selector( MyViewProtocol.myTouchBegan(point:) )).map { a in
 
 return a[0] as! CGPoint
 
 }
 
 return ControlEvent(events: source)
 
 }
 


 
}
 

调用

  myView = MyView(frame: self.view.frame)
 
        myView?.backgroundColor = UIColor.gray
 
 self.view.addSubview(myView!)
 
        myView?.rx.touch.subscribe(onNext: { point in
 
 print(point)
 
 }, onError: { (e:Error) in
 


 
 }, onCompleted: {
 


 
 }, onDisposed: {
 


 
 })
 

避免了delegate是不是很方便啊

实现基本原理

rx这个方式通过自定义委托Proxy来实现,也就是代理的代理来实现

1 定义一个委托

继承于Rx定义的好的委托Proxy的模版 class RxMyViewProxy: DelegateProxy, MyViewProtocol, DelegateProxyType {}

分析:

DeleProxy 采用泛型的方式,同时限定了被委托的Target为MyView以及定的Protocol
 
与此同时作为代理的代理同时需要遵循限定的Protocol
 
通过DelegateProxyType限定一下代理的委托类型
 

2 让被代理的Target需要HasDelegate来表明对应的关联类型进行类型推导

extension MyView: HasDelegate {
 
 public typealias Delegate = MyViewProtocol
 
}

3 实现DelegateProxyType的静态fun 进行类注册和内部代理赋值与获取

 static func setCurrentDelegate(_ delegate: MyViewProtocol?, to object: MyView) {
 
 object.delegate = delegate
 
 }
 
 static func currentDelegate(for object: MyView) -> MyViewProtocol? {
 
 return object.delegate
 
 }
 
 static func registerKnownImplementations() {
 
 self.register {
 
 return RxMyViewProxy(view: $0)
 
 }
 
 }
 

4 扩展Reactive实现cocoa UI类的rx扩展

extension Reactive where Base: MyView {
 
 var rxDelegate: RxMyViewProxy {
 
 return RxMyViewProxy.proxy(for: self.base)
 
 }
 
 var touch:ControlEvent<CGPoint>{
 
 let source = self.rxDelegate.methodInvoked(#selector( MyViewProtocol.myTouchBegan(point:) )).map { a in
 
 return a[0] as! CGPoint
 
 }
 
 return ControlEvent(events: source)
 
 }
 


 
}

本文分享自微信公众号 - 大话swift(gh_ca2266b7cab0),作者:YuLongLi

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • YYModel使用的小技巧

    作为iOS开发的著名三方库YYKit可以说是家喻户晓,是一个集大成的开源库,今天我们说一下关于旗下的JSON转换功能小技巧

    大话swift
  • vapor 之 cache记录

    为了后续修改方便我们进行了alias ```typealias IACache = SQLiteCache```

    大话swift
  • vapor实现 安装包和历史版本查看

    阅读VaporStyle指导之后突然感觉写代码思路变慢了很多,思路总是被终端,明显感觉不适应那种代码和思维方式,不过强制扭转之后感觉代码组织和易读性明显提高了,...

    大话swift
  • 360 P1 无线路由器IP/MAC绑定操作方法

    首先,在浏览器地址栏中输入您安全路由的管理地址(通用地址:luyou.360.cn 或 默认地址:192.168.0.1),然后,输入管理密码(默认为WiFi密...

    砸漏
  • 10. Python 帮助

    int()   str()    dict()   list()   tuple()   一般是这几种类型的转换

    py3study
  • 百度贴吧 | 通用抓图脚本搞专业爬虫的话,先保证网速够好,再考虑多进程还是多线程~

    多进程优势:单个进程的崩溃,不会影响其它进程 随之而来的问题是,进程之间,资源不共享,信息不共享,所以进程通讯的问题,是实现多进程协作,必须解决的问题 ...

    zhaoolee
  • 小程序开发采的几个坑

    如果我们使用的是自定义导航模式(navigationStyle: 'custom'),一般则需要通过此函数来获取菜单按钮的信息:

    IMWeb前端团队
  • 测试中的图

    我们首先介绍如何从软件当中产生图及图的基本定义。图当中,如何去选择它的路径,如何产生测试路径。 曾经有人说过,所谓软件测试,就是把软件变成一张图,然后覆盖它。由...

    归根落叶
  • Python学习之面向对象「 中 」

    Python技术与生活认知的分享
  • Spring对象解析及注册(二)

    前面对Spring解析对象的整体做些整理,下面进出核心方法registerBeanDefinitions

    OPice

扫码关注云+社区

领取腾讯云代金券