我想阻止我的UIButtons发出RX tap事件,直到一些控制流指示它已准备就绪。如果控制流恢复到未准备好,我希望再次禁用按钮。控制序列是ReplaySubject
并且总是有价值的
我尝试了skipUntil
,但这是一次性操作 - 一旦控制序列发出,它就不能回到禁用状态 - 所有按钮按下都会通过,忽略控制序列
除非某些其他流具有特定值,否则如何限制UIButton发送tap事件?
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/dtartaglia/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) -> (E, Bool) in
return (myValue, triggerValue)
}
.filter { (myValue, triggerValue) -> Bool in
return triggerValue == true
}
.map { (myValue, triggerValue) -> E 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)