这是将Swift协议转换为RxDelegateProxy的最佳方法吗?

时间:2018-01-18 07:42:05

标签: ios swift rx-swift

抱歉,我无法想出更好的头衔,如果有人建议更好的话,我会修改它。

我有一个协议

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

问题

  1. 因为没有任何在线教程(Raywenderlich)/课程(Udemy)/书籍(Raywenderlich)解释如何将swift协议转换为Rx风格我感到很困惑,因为我在做什么是对还是错。代码可以工作,但即使设计最差的代码也可以工作,因此我想确定正在做什么是正确的还是搞乱了。我按照UIScrollView+Rx.swiftRxScrollViewDelegateProxy.swift

  2. 中使用的方法编写了上述代码
  3. 虽然上面的代码仅适用于没有任何返回类型的协议,但我在func scrollViewShouldScrollToTop()上面使用的返回类型没有与之关联的返回类型。我无法想象如何使用上面的DelegateProxy将协议方法转换为返回类型,例如numberOfRowsInSection,其中Int为返回类型。

  4. 我碰巧看了RxDataSource实现并实现了转换cellForRowAtIndexPath RxDataSource构造函数要求您将块作为init参数传递并在tableView调用时执行它{{ 1}}在其proxyDelegate中。

    现在我可以做同样的事情,如果这是唯一的出路。需要知道的是我应该如何编码它,或者我可以修改上面的ProxyDelegate实现来转换带有返回类型的协议方法。

0 个答案:

没有答案