Reputation: 159
I have two UITextField
and one UITableView
in one UIViewController
. The ViewModel of this UIViewController
exposes one Observable to be the table view datasouce. The two UITextField
take the parameters from users and refresh the table view Observable. UITextField
are using UIPickerView
as InputView and those UIPickerViews
are using a custom class as the adapter.
In UIViewController:
//bind the adapter to the UIPickerView
self.viewModel.dateList.bind(to: self.datePickerView.rx.items(adapter: self.viewModel.pickerViewAdapter)).disposed(by: rx.disposeBag)
In ViewModel:
let dateList = Observable.just([[Int](0...1), [Int](1...12)])
final class PickerViewViewAdapter
: NSObject
, UIPickerViewDataSource
, UIPickerViewDelegate
, RxPickerViewDataSourceType
, SectionedViewDataSourceType {
typealias Element = [[Int]]
private var items: [[Int]] = []
var activeTextField:UITextField!
func model(at indexPath: IndexPath) throws -> Any {
return items[indexPath.section][indexPath.row]
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return items.count
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return items[component].count
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let label = UILabel()
if component == 0{
label.text = "\(2018 - items[component][row])"
}else{
label.text = "\(items[component][row])"
}
label.font = UIFont.preferredFont(forTextStyle: .title1)
label.textAlignment = .center
return label
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int){
///
/// Need to update the UITextField.text in a specific form
///
}
func pickerView(_ pickerView: UIPickerView, observedEvent: Event<Element>) {
Binder(self) { (adapter, items) in
adapter.items = items
pickerView.reloadAllComponents()
}.on(observedEvent)
}
}
After the user select from UIPickerView
I need to update the UITextField.text
in a specific form, and then use those text as the parameters for the API.
How should I do this in a Reactive way in MVVM?
Upvotes: 1
Views: 950
Reputation: 33979
I'm not sure about what all is happening in your code, but maybe this will help out:
let items = Observable.just(Calendar.current.monthSymbols)
let pickerView = UIPickerView()
textField.inputView = pickerView
// this pipe displays the items in the picker view
items
.bind(to: pickerView.rx.itemTitles) { $1 }
.disposed(by: bag)
// this pipe displays the picked item in the text field
Observable.combineLatest(items, pickerView.rx.itemSelected) { $0[$1.row] }
.bind(to: textField.rx.text)
.disposed(by: bag)
Upvotes: 2