RxCocoa中的UICollectionViewDelegate

时间:2018-11-04 16:10:24

标签: rx-swift rx-cocoa

我为UICollectionView编写了一个扩展,它将监听委托的 shouldHighlightItemAt方法,但不调用。

public var shouldHighlightItem: ControlEvent<IndexPath> {

    let source = self.delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:shouldHighlightItemAt:)))
        .map { a in
            return try self.castOrThrow(IndexPath.self, a[1])
    }

    return ControlEvent(events: source)
}

}

如何为rx shouldHighlightItemAt编写UICollectionView的扩展?

1 个答案:

答案 0 :(得分:1)

您不能将methodInvoked(_:)与具有非void返回类型的委托方法一起使用。

collectionView(_:shouldHighlightItemAt:)希望您返回一个Bool值。因此,您不能使用methodInvoked(_:)

如果您查看methodInvoked(_:)的实现,则会为您解释为什么它不起作用:

  

无法观察到具有非void返回值的委托方法   直接使用这种方法            因为:

     
      
  • 这些方法不打算用作通知机制,而是用作行为定制机制

  •   
  • 没有明智的自动方法来确定默认返回值

  •   

但是有一个建议可以帮助您实现自己的目标:

  

如果观察到具有返回类型的委托方法是   需要,可以通过            手动安装PublishSubjectBehaviorSubject并实现委托方法。

在您的情况下,它将像这样工作:

RxCollectionViewDelegateProxy中,添加“ PublishSubject”并实现UICollectionViewDelegate方法:

let shouldHighlightItemAtIndexPathSubject = PublishSubject<IndexPath>

public func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
    shouldHighlightItemAtIndexPathSubject.on(.next(indexPath))
    return self._forwardToDelegate?.collectionView(collectionView, shouldHighlightItemAt: indexPath) ?? true // default value
}

在UICollectionView RxExtension中,您可以像这样公开所需的Observable:

public var property: Observable<IndexPath> {
    let proxy = RxCollectionViewDelegateProxy.proxy(for: base)
    return proxy.shouldHighlightItemAtIndexPathSubject.asObservable()
}

我还没有测试过,我只是从RxCocoa源代码中获取并修改了它以满足您的需求。因此,从理论上讲,这应该可行,但是您可能需要对其进行一些调整;-)