我们有一个视图控制器MainCollectionView
,其中包含一个带有许多单元格FooCell
的集合视图。在每个FooCell
内部,都有一个收集视图和一个BarCell
单元列表。
如何在BarCell
中将按钮点击事件传播到MainCollectionView
?
这就是我们所拥有的:
class FooCell: ... {
private let barCellButtonTappedSubject: PublishSubject<Void> = PublishSubject<Void>()
var barCellButtonTappedObservable: Observable<Void> {
return barCellButtonTappedSubject.asObserver()
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeue(...)
if let cell = cell as BarCell {
cell.button.rx.tap.bind { [weak self] in
self?.barCellButtonTappedSubject.onNext(())
}.disposed(by: cell.rx.reusableDisposeBag)
}
return cell
}
}
class MainCollectionView: ... {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeue(...)
if let cell = cell as FooCell {
cell.barCellButtonTappedObservable.subscribe { [weak self] in
// Do other stuff when the button inside bar cell is tapped.
}.disposed(by: cell.rx.reusableDisposeBag)
}
return cell
}
}
在我阅读有关
ControlEvent
之前,此方法将起作用:似乎更适合在
ControlEvent
中使用FooCell
:private let barCellButtonTappedSubject: PublishSubject<Void> = PublishSubject<Void>()
var barCellButtonTappedObservable: Observable<Void> {
return barCellButtonTappedSubject.asObserver()
}
将此
barCellButtonTappedObservable
转换为ControlEvent
的正确方法是什么?还是有其他更好的主意将嵌套单元格中的ControlEvent
传播到外部视图控制器? 最佳答案
我个人更喜欢将RxAction
用于此类内容,但是由于您已经在单元格中声明了PublishSubject<Void>
,因此可以将主题转换为ControlEvent
controlEvent = ControlEvent<Void>(events: barCellButtonTappedSubject.asObservable())
尽可能直接!但是,如果您只想这样做,那么您甚至不需要
barCellButtonTappedSubject
controlEvent = ControlEvent<Void>(events: cell.button.rx.tap)
实际上,您甚至不需要声明控制事件:)因为
cell.button.rx.tap
本身是一个控制事件:)因此,如果您在单元格中将按钮声明为 public 属性,则可以在tableView控制器中直接访问其tap控制事件。但就我个人而言,我会使用
RxAction
而不是声明一个publishSubject
或controlEvent
您的FooCell
可以要求您的TableViewController
采取措施class FooCell: ... {
var cellTapAction : CocoaAction! = nil
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeue(...)
if let cell = cell as BarCell {
cell.button.rx.action = cellTapAction
}
return cell
}
}
最后,您的TableViewController / CollectionViewController可以将操作传递为
class MainCollectionView: ... {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeue(...)
if var cell = cell as FooCell {
cell.cellTapAction = CocoaAction { _ -> Observable<Void> in
debugPrint("button in cell tapped")
return Observable.just(())
}
}
return cell
}
}
唯一需要处理的就是是否将cellctionView嵌入到
FooCell
中,因为即使在传递给action
嵌入式collectionView之后也可能会加载deQueReusableCell
,所以您甚至必须调整逻辑以在将动作传递给它之后重新加载嵌入的collection视图。 FooCell
或任何其他可解决此问题的解决方法:)希望对您有所帮助:)我相信使用
Action
可以使代码更整洁且易于理解。关于ios - 如何将`Observable`转换为`ControlEvent`,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52992332/