事情不多主要是讲讲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
微信扫一扫打赏
支付宝扫一扫打赏