Ale*_*one 6 reactive-programming control-flow ios swift rx-swift
我想阻止我的 UIButtons 发出 RX tap 事件,直到某些控制流表明它已准备就绪。如果控制流恢复为未准备好,我希望再次禁用按钮。控制序列是一个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)
}
Run Code Online (Sandbox Code Playgroud)
这是我不久前写的并在下面复制的内容。如果您查看我的要点(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
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想根据控件 observable 的值更改按钮的作用,请设置两个过滤器。通常,过滤器仅在enableButtons发出 true时才通过抽头。在第二种情况下使用地图将其反转,然后直接按钮点击另一条路径:
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2821 次 |
| 最近记录: |