如何在不创建无限循环的情况下让 RxSwift 中的主题将值推送给自身

How to have a subject in RxSwift push values to itself without creating an infinite loop

我有一个 UITableView,如果满足某些条件,我想将其置于编辑状态。切换编辑的主要方式是通过编辑按钮。

所以我的视图元素是

let tableView = UITableView()
let editButton = UIButton()

以及 tableView 是否应该处于编辑模式来自:

let editing = BehaviorSubject(value: false)

它将使用类似以下内容连接到 tableView:

editing.subscribeNext { isEditing in
  tableView.setEditing(isEditing, animated: true)
}

点击编辑按钮时,我希望将新值推送到 editing,即对发送到 editing 的最新值取反。最近的值可能是通过点击 editButton 设置的,也可能来自其他地方。

我不明白如何将按钮按下的流与 editing 的流结合起来,从而允许在没有无限循环的情况下进行此操作,例如

Obervable.combineLatest(editButton.rx_tap.asObservable(), editing) { _, isEditing in
  editing.onNext(!isEditing)
}

我知道 tableView 有一个 editing 属性,但我不想依赖它,因为我正在寻找可以重复使用的更通用的解决方案别处。我也不打算在实例 var 中跟踪 isEditing 的值,甚至作为 Variable(),因为我正在寻找一种无状态的、基于流的解决方案(如果可能的话)。

谢谢!

如果您将 editing 定义为 Variable 而不是 BehaviourSubject 会怎么样? Variable 不会出错,这在这种情况下是有意义的。声明如下所示:

let editing = Variable(value: false)

您可以订阅按钮点击并将 editing 的值更改为取反的当前值:

editButton.rx_tap.asObservable().subscribeNext { editing.value = !editing.value }

随着改变editingvalue属性这个方法被调用

editing.subscribeNext { isEditing in
    tableView.setEditing(isEditing, animated: true)
}

所有这些都没有经过测试,但可能会引导您朝着正确的方向寻找正确的解决方案。

在 RxSwift GitHub 问题论坛的帮助下,我现在已经解决了 :)。关键是 withLatestFrom。我在下面包含了一个示例,以防它对其他人有所帮助。 editButton 是触发编辑模式打开或关闭的主要方式,我已经包含了通过 tableView.rx_itemSelected 发送的事件作为附加输入示例(在这种情况下,我希望编辑在任何时候结束一个项目被选中)。

let isEditing = BehaviorSubject(value: false)
let tableView = UITableView()
let editButton = UIButton()

tableView.rx_itemSelected
  .map { _ in false }
  .bindTo(isEditing)

editButton.rx_tap.withLatestFrom(isEditing)
  .map { ![=10=] }
  .bindTo(isEditing)

isEditing.subscribeNext { editing in
  tableView.setEditing(editing, animated: true)
}

注意:每次选择项目时,此解决方案都会将 .Next(false) 发送到 isEditing,即使 table 当前未处于编辑模式。如果你觉得这是一件坏事,并且想要过滤 rx_itemSelected 以仅在 table 实际上处于编辑模式时发送 .Next(false),你可能可以使用 [= 的组合来做到这一点11=] 和 filter.