前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Rx实现自定义类Delegate

Rx实现自定义类Delegate

作者头像
大话swift
发布2020-05-22 18:34:25
8700
发布2020-05-22 18:34:25
举报
文章被收录于专栏:大话swift大话swift

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

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

代码语言:javascript
复制


 
@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扩展

代码语言:javascript
复制

 
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)
 
 }
 


 
}
 

调用

代码语言:javascript
复制
  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 {}

分析:

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

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

代码语言:javascript
复制
extension MyView: HasDelegate {
 
 public typealias Delegate = MyViewProtocol
 
}

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

代码语言:javascript
复制
 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扩展

代码语言:javascript
复制
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)
 
 }
 


 
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大话swift 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Rx方式通过自定义VIew通过代理实现点击获取点击位置
  • 实现Rx扩展
    • 调用
    • 实现基本原理
      • 1 定义一个委托
        • 分析:
      • 2 让被代理的Target需要HasDelegate来表明对应的关联类型进行类型推导
        • 3 实现DelegateProxyType的静态fun 进行类注册和内部代理赋值与获取
          • 4 扩展Reactive实现cocoa UI类的rx扩展
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档