Отключение кнопки на основе значения в UITextField работает только один раз (RxSwift) - PullRequest
0 голосов
/ 31 мая 2019

Я пытаюсь справиться с RxCocoa и столкнулся с необычной ошибкой, связанной с некоторым поведением динамического интерфейса, который я пытаюсь реализовать.

У меня есть UITextField, который используется для пользовательского ввода. Кнопка, которая добавляет ввод в базу данных Realm, привязана к действию RxSwift. Это работает абсолютно нормально.

Изначально я отключал кнопку до тех пор, пока в UITextField не было текста длиной не менее 1 символа - код работает нормально. Ошибка в моем коде возникла, когда я затем добавил подписку к параметру actionObservables действия, которая должна очищать UITextField после нажатия кнопки.

Ожидаемое поведение:

  • Нет текста (исходное состояние)> кнопка отключена
  • Введенный текст> кнопка включена
  • Ввод текста и нажатие кнопки> очистить текстовое поле и отключить кнопку

Фактическое поведение:

  • Нет текста (исходное состояние)> кнопка отключена
  • Введенный текст> кнопка включена
  • Введенный текст и нажатая кнопка> очищенное текстовое поле НО кнопка остается включенной

Добавление debug () указывает на то, что привязка к UITextField, который отключает кнопку, удаляется, но я не могу понять, почему UIViewController и связанная с ним модель представления все еще должны находиться в области видимости. Кто-нибудь может указать мне правильное направление?

Фрагмент кода:

func bindViewModel() {
    // populate table
    viewModel.output.sectionedObservations
        .drive(tableView.rx.items(dataSource: dataSource))
        .disposed(by: disposeBag)

    // only allow enable button when there is text in the textfield
    observationTextField.rx.text
        .debug()
        .map { $0!.count > 0 }
        .bind(to: addObservationButton.rx.isEnabled)
        .disposed(by: disposeBag)

// clear textfield once Action triggered by button press has completed
viewModel.addObservation.executionObservables
    .subscribe({ [unowned self] _ in
        self.observationTextField.rx.text.onNext("")
})
.disposed(by: disposeBag)

// add Observation to Realm using Action provided by the view model
addObservationButton.rx.tap
    .withLatestFrom(observationTextField.rx.text.orEmpty)
    .take(1)
    .bind(to: viewModel.addObservation.inputs)
    .disposed(by: disposeBag)
}

1 Ответ

1 голос
/ 31 мая 2019

Я думаю, есть небольшое недоразумение о том, как ведет себя черта ControlProperty. Давайте посмотрим на конкретное поведение, которое Программные значения не будут сообщаться

Эта наблюдаемая observationTextField.rx.text после подписки не будет генерировать событие для обоих:

self.observationTextField.rx.text.onNext("")

или

self.observationTextField.text = ""

У меня есть 2 предложения для вашего кода:

1) Выполните работу вручную:

viewModel.addObservation.executionObservables
    .subscribe({ [unowned self] _ in
        self.observationTextField = ""
        self.addObservationButton.isEnabled = false
})
.disposed(by: disposeBag)

2) Добавить еще одну Наблюдаемую и подписку:

//a
    viewModel.addObservation.executionObservables
      .map { _ in return "" }
      .bind(to: observationTextField.rx.text)
      .disposed(by: disposeBag)

    viewModel.addObservation.executionObservables
      .map { _ in return false }
      .bind(to: addObservationButton.rx.isEnabled)
      .disposed(by: disposeBag)
//b
    let executionObservables = viewModel.addObservation
      .executionObservables
      .share()

    executionObservables
      .map { _ in return "" }
      .bind(to: observationTextField.rx.text)
      .disposed(by: disposeBag)

    executionObservables
      .map { _ in return false }
      .bind(to: addObservationButton.rx.isEnabled)
      .disposed(by: disposeBag)

Не уверен, как реализован Action, чтобы предотвратить выполнение работы дважды, возможно, вам придется делиться ресурсами.

...