我想阻止我的UIButtons发出RX点击事件,直到某个控制流指示它已准备就绪。我希望在控制流恢复为未就绪时再次禁用按钮。控制序列是一个ReplaySubject
,并且始终具有值
我已经尝试了skipUntil
,但这是一个一次性操作 - 一旦控制序列发出,它就无法返回到禁用状态 - 所有按钮按下都会通过,忽略控制序列
如何限制 UIButton 发送点击事件,除非其他流具有特定值?
let enableButtons = configStatusInputSequence
.filter { (configured, ready) -> Bool in
return configured && ready
}
for button in controlButtons{
button.rx.tap
.skipUntil(enableButtons)
.bind(to: commandOutputSequence)
.disposed(by: bag)
}
这是我不久前写的并在下面复制的内容。如果您查看我的要点(https://gist.github.com/danielt1263/1a70c4f7b8960d06bd7f1bfa81802cc3(,您会发现我最初将其编写为自定义运算符。后来我才知道,下面内置运算符的组合可以完成相同的工作。
如果不出意外,回顾一下 gist 中的旧修订版会让您了解如何编写自己的运算符。
extension ObservableType {
/**
Filters the source observable sequence using a trigger observable sequence producing Bool values.
Elements only go through the filter when the trigger has not completed and its last element was true. If either source or trigger error's, then the source errors.
- parameter trigger: Triggering event sequence.
- returns: Filtered observable sequence.
*/
func filter(if trigger: Observable<Bool>) -> Observable<E> {
return withLatestFrom(trigger) { (myValue, triggerValue) -> (Element, Bool) in
return (myValue, triggerValue)
}
.filter { (myValue, triggerValue) -> Bool in
return triggerValue == true
}
.map { (myValue, triggerValue) -> Element in
return myValue
}
}
}
如果要根据控件可观察值更改按钮的功能,请设置两个筛选器。通常,滤波器仅在enableButtons
发出真时通过抽头。在第二种情况下,使用地图将其反转,并直接点击另一条路径:
button.rx.tap.filter(if: enableButtons)
.subscribe(onNext: { /* do one thing when enableButtons emits true */ }
.disposed(by: bag)
button.rx.tap.filter(if: enableButtons.map { !$0 })
.subscribe(onNext: { /* do other thing when enable buttons emits false*/ }
.disposed(by: bag)