基于 UITextField 中的值禁用按钮只能工作一次(RxSwift)
Disabling a button based on value in a UITextField only works once (RxSwift)
我正在尝试掌握 RxCocoa
并且遇到了一个与我尝试实现的某些动态 UI 行为相关的异常错误。
我有一个 UITextField
用于用户输入。将输入添加到 Realm 数据库的按钮绑定到 RxSwift
操作。这绝对没问题。
最初,我禁用了按钮,直到 UITextField
中出现长度至少为 1 个字符的文本 - 此代码工作正常。当我添加对 Action 的 executionObservables 参数的订阅时,我的代码中出现了错误,该参数应在按下按钮后清除 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 { [=10=]!.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)
}
我认为对 ControlProperty
trait 的行为方式存在一些误解。让我们来看看具体的行为是Programmatic value changes won't be reported
订阅后的这个 Observable 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) 再添加一个 Observable 和订阅:
//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
是如何实现的,为了防止工作完成两次,您可能必须共享资源。
我正在尝试掌握 RxCocoa
并且遇到了一个与我尝试实现的某些动态 UI 行为相关的异常错误。
我有一个 UITextField
用于用户输入。将输入添加到 Realm 数据库的按钮绑定到 RxSwift
操作。这绝对没问题。
最初,我禁用了按钮,直到 UITextField
中出现长度至少为 1 个字符的文本 - 此代码工作正常。当我添加对 Action 的 executionObservables 参数的订阅时,我的代码中出现了错误,该参数应在按下按钮后清除 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 { [=10=]!.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)
}
我认为对 ControlProperty
trait 的行为方式存在一些误解。让我们来看看具体的行为是Programmatic value changes won't be reported
订阅后的这个 Observable 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) 再添加一个 Observable 和订阅:
//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
是如何实现的,为了防止工作完成两次,您可能必须共享资源。