RxCocoa 中的 UICollectionViewDelegate
UICollectionViewDelegate in RxCocoa
我为 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 编写扩展?
您不能将 methodInvoked(_:)
与具有非 void return 类型的委托方法一起使用。
collectionView(_:shouldHighlightItemAt:)
期望您 return 一个 Bool
值。所以你不能使用 methodInvoked(_:)
.
如果你看一下 methodInvoked(_:)
的实现,它会解释为什么这不起作用:
Delegate methods that have non void
return value can't be observed
directly using this method
because:
those methods are not intended to be used as a notification mechanism, but as a behavior customization mechanism
there is no sensible automatic way to determine a default return value
不过,有一个建议可以帮助您实现目标:
In case observing of delegate methods that have return type is
required, it can be done by
manually installing a PublishSubject
or BehaviorSubject
and implementing delegate method.
在你的情况下它会像这样工作:
在 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 源代码中获取它并修改它以满足您的需要。所以理论上这应该可行,但您可能需要稍微调整一下 ;-)
我为 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 编写扩展?
您不能将 methodInvoked(_:)
与具有非 void return 类型的委托方法一起使用。
collectionView(_:shouldHighlightItemAt:)
期望您 return 一个 Bool
值。所以你不能使用 methodInvoked(_:)
.
如果你看一下 methodInvoked(_:)
的实现,它会解释为什么这不起作用:
Delegate methods that have non
void
return value can't be observed directly using this method because:
those methods are not intended to be used as a notification mechanism, but as a behavior customization mechanism
there is no sensible automatic way to determine a default return value
不过,有一个建议可以帮助您实现目标:
In case observing of delegate methods that have return type is required, it can be done by manually installing a
PublishSubject
orBehaviorSubject
and implementing delegate method.
在你的情况下它会像这样工作:
在 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 源代码中获取它并修改它以满足您的需要。所以理论上这应该可行,但您可能需要稍微调整一下 ;-)