抱歉,我无法想出更好的头衔,如果有人建议更好的话,我会修改它。
我有一个协议
@objc public protocol MyCollectionViewProtocol {
func scrollViewShouldScrollToTop()
}
我已将其声明为@objc
,因为遗憾的是,DelegateProxy不能与非NSObject协议一起工作(我认为,如果有人能够澄清这一点,那将是一个很好的帮助)
我的collectionView
public class MyCollectionView: UICollectionView {
weak var cvDelegate : MyCollectionViewProtocol?
... //rest of the code isnt related to this question in particular
现在我将委托代理声明为
open class RxMyCollectionViewDelegateProxy : DelegateProxy<MyCollectionView, MyCollectionViewProtocol>
, DelegateProxyType
, MyCollectionViewProtocol {
public static func currentDelegate(for object: MyCollectionView) -> MyCollectionViewProtocol? {
return object.cvDelegate
}
public static func setCurrentDelegate(_ delegate: MyCollectionViewProtocol?, to object: MyCollectionView) {
object.cvDelegate = delegate
}
public weak private(set) var collectionView: MyCollectionView?
internal lazy var shouldScrollPublishSubject: PublishSubject<Void> = {
let localSubject = PublishSubject<Void>()
return localSubject
}()
public init(collectionView: ParentObject) {
self.collectionView = collectionView
super.init(parentObject: collectionView, delegateProxy: RxMyCollectionViewDelegateProxy.self)
}
// Register known implementations
public static func registerKnownImplementations() {
self.register { RxMyCollectionViewDelegateProxy(collectionView: $0) }
}
//implementation of MyCollectionViewProtocol
public func scrollViewShouldScrollToTop() {
shouldScrollPublishSubject.onNext(())
self._forwardToDelegate?.scrollViewShouldScrollToTop()
}
deinit {
shouldScrollPublishSubject.onCompleted()
}
}
最后,我将MyCollectionView的Reactive扩展名声明为
extension Reactive where Base: MyCollectionView {
public var delegate: DelegateProxy<MyCollectionView, MyCollectionViewProtocol> {
return RxMyCollectionViewDelegateProxy.proxy(for: base)
}
public var shouldScrollToTop: ControlEvent<Void> {
let source = RxMyCollectionViewDelegateProxy.proxy(for: base).shouldScrollPublishSubject
return ControlEvent(events: source)
}
}
最后,我将其用作
collectionView.rx.shouldScrollToTop.debug().subscribe(onNext: { (state) in
print("I should scroll to top")
}, onError: { (error) in
print("errored out")
}, onCompleted: {
print("completed")
}, onDisposed: {
print("Disposed")
}).disposed(by: disposeBag)
问题
因为没有任何在线教程(Raywenderlich)/课程(Udemy)/书籍(Raywenderlich)解释如何将swift协议转换为Rx风格我感到很困惑,因为我在做什么是对还是错。代码可以工作,但即使设计最差的代码也可以工作,因此我想确定正在做什么是正确的还是搞乱了。我按照UIScrollView+Rx.swift
和RxScrollViewDelegateProxy.swift
虽然上面的代码仅适用于没有任何返回类型的协议,但我在func scrollViewShouldScrollToTop()
上面使用的返回类型没有与之关联的返回类型。我无法想象如何使用上面的DelegateProxy将协议方法转换为返回类型,例如numberOfRowsInSection
,其中Int
为返回类型。
我碰巧看了RxDataSource
实现并实现了转换cellForRowAtIndexPath
RxDataSource
构造函数要求您将块作为init参数传递并在tableView调用时执行它{{ 1}}在其proxyDelegate中。
现在我可以做同样的事情,如果这是唯一的出路。需要知道的是我应该如何编码它,或者我可以修改上面的ProxyDelegate实现来转换带有返回类型的协议方法。