RxSwift, как условно контролировать, когда кнопка издает нажатия? - PullRequest
0 голосов
/ 09 сентября 2018

Я хочу запретить моим UIB-кнопкам отправлять события касания 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)
}

1 Ответ

0 голосов
/ 09 сентября 2018

Вот кое-что, что я написал некоторое время назад и воспроизвел ниже. Если вы посмотрите на мою суть (https://gist.github.com/dtartaglia/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) -> (E, Bool) in
                return (myValue, triggerValue)
            }
            .filter { (myValue, triggerValue) -> Bool in
                return triggerValue == true
            }
            .map { (myValue, triggerValue) -> E in
                return myValue
            }
    }
}

Если вы хотите изменить действие кнопки в зависимости от значения наблюдаемого элемента управления, настройте два фильтра. Обычно фильтр проходит через касания только тогда, когда 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)
...