benoitcn
benoitcn

Reputation: 159

RxSwift MVVM implemention inquire

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

Answers (1)

Daniel T.
Daniel T.

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

Related Questions