gpt4 book ai didi

ios - 如何将 `Observable` 转换为 `ControlEvent`

转载 作者:行者123 更新时间:2023-11-28 11:43:34 25 4
gpt4 key购买 nike

我们有一个 View Controller MainCollectionView,它包含一个带有多个单元格 FooCell 的 Collection View 。在每个 FooCell 中,都有一个 Collection View 和一个单元格列表 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 之前,这是有效的:

  • 它永远不会失败
  • 它不会在订阅时发送任何初始值
  • 它将在释放控制权时完成序列
  • 它永远不会出错
  • 它在 MainScheduler.instance 上传递事件

看起来在FooCell中使用ControlEvent比较合适:

private let barCellButtonTappedSubject: PublishSubject<Void> = PublishSubject<Void>()
var barCellButtonTappedObservable: Observable<Void> {
return barCellButtonTappedSubject.asObserver()
}

将此 barCellButtonTappedObservable 转换为 ControlEvent 的正确方法是什么?或者是否有其他更好的想法将嵌套单元格中的 ControlEvent 传播到外部 View Controller ?

最佳答案

我个人更喜欢使用 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 Controller 中访问它的点击控制事件

但就我个人而言,我会使用 RxAction而不是声明 publishSubjectcontrolEvent你的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 中因为我路过actiondeQueReusableCell 之后嵌入式 collectionView 甚至可能在操作传递给它之前加载,因此您必须调整逻辑以在操作传递给 FooCell 后重新加载嵌入式 Collection View 。或任何其他解决此问题的解决方法:)

希望对您有所帮助 :) 我相信使用 Action使代码更清晰,更易于理解。

关于ios - 如何将 `Observable` 转换为 `ControlEvent`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52992332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com