这是将Swift协议转换为RxDelegateProxy的最佳方法吗?
对不起,我无法想出比这更好的标题,如果有人建议更好的一个,我会修改它。
我有一个协议
@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 , 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 = { let localSubject = PublishSubject() 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 { return RxMyCollectionViewDelegateProxy.proxy(for: base) } public var shouldScrollToTop: ControlEvent { 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来转换带有返回类型的协议方法,例如将Int
作为返回类型的numberOfRowsInSection
。
我碰巧看了RxDataSource
实现并实现了转换cellForRowAtIndexPath
RxDataSource
构造函数希望您将块作为init参数传递,并在tableView在其proxyDelegate中调用cellForRowAtIndexPath
时执行它。
现在我可以做同样的事情,如果这是唯一的出路。 需要知道的是我应该如何编码它,或者我可以修改上面的ProxyDelegate实现来转换带有返回类型的协议方法。