ios - RxSwift 如何有条件地控制按钮何时发出水龙头?

标签 ios swift reactive-programming rx-swift control-flow

我想阻止我的 UIButton 发出 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 ),您会发现我最初将其编写为自定义运算符。后来我了解到,下面的内置运算符组合可以完成相同的工作。

如果不出意外,回顾一下要点中的旧版本会让您了解如何编写自己的运算符。

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 发出 true 时通过点击。在第二种情况下使用 map 将其反转,然后直接按钮点击另一条路径:

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)

关于ios - RxSwift 如何有条件地控制按钮何时发出水龙头?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52243856/

相关文章:

ios - 每月启动一次 UIalert View

ios - 如何让键盘显示但不覆盖屏幕 Swift 4 底部的元素?

ios - 如何在 Swift 中仅显示在我的应用程序上创建的一张专辑?

swift - UISearchBar 不适用于数组中的子部分

javascript - 函数式响应式(Reactive)编程 (FRP) 可以用 monad 表达吗?

iphone - 方法引用

swift - ARKit – eulerAngles of Transform Matrix 4x4

ios - 如何在 Swift 3 中的图像上添加不透明的黑色

javascript - RxJS:每隔x秒进行一次

javascript - 如何在 RxJS 中通过 ID 去抖