事情不多主要是讲讲Rx如何自定义代理,为啥要将这个只要是iOS中太多的delegate 话不多说我们先来代码
@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))
}
}
}
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来实现,也就是代理的代理来实现
继承于Rx定义的好的委托Proxy的模版 class RxMyViewProxy: DelegateProxy, MyViewProtocol, DelegateProxyType {}
DeleProxy 采用泛型的方式,同时限定了被委托的Target为MyView以及定的Protocol
与此同时作为代理的代理同时需要遵循限定的Protocol
通过DelegateProxyType限定一下代理的委托类型
extension MyView: HasDelegate {
public typealias Delegate = MyViewProtocol
}
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)
}
}
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)
}
}