0
votes

Below is a simple example of binding a string array of viewModel to UITableView.

I want to subscribe to one more viewModel.randomString and use it in the cell.
I tried using combineLatest as below, but of course I couldn't bind to tableview.
Do you have any ideas on how to implement it?

class SimpleViewModel {
    var list = BehaviorRelay<[String]>(value: [])
    var randomString = BehaviorRelay<String>(value: "")
    
    func fetch() {
        // Request...
        list.accept(["result1", "result2", "result3"])
        randomString.accept("Random...")
    }
}

class SimpleViewController {
    let tableView = UITableView()
    let viewModel = ViewModel()
    
    func foo() {
        // It works well.
        viewModel.list.bind(to: tableView.rx.items(cellIdentifier: "Cell")) { (index, element, cell) in
            cell.textLabel?.text = element
        }
        
        // I want to bind the viewModel.list to the tableView and use the viewModel.randomString string together.
        Observable.combineLatest(viewModel.list, viewModel.randomString)
        // How???
//            .bind(to: tableView.rx.items(cellIdentifier: "Cell")) { (index, element, cell) in
//                cell.textLabel?.text = element + "RandomString" // I want to use the "RandomString" of viewModel.randomString
//            }
    }
}
1

1 Answers

1
votes

Your combineLatest call produces a Observable<([String], String)>, but in order to bind to the table view items, you need an observable of a Sequence of things.

([String], String) is not a sequence. It is a pair of things. You need to find a way to convert that to a sequence of things. Since you want the same randomString for each cell, you can use a function like this:

{ (list, randomString) in list.map { (element: $0, randomString: randomString) } }

to convert that to a [(String, String)], with the second string in each pair in the array being the randomString.

If you just pass the above function to Observable.map, you can convert a Observable<([String], String)> to Observable<[(String, String)]>:

Observable.combineLatest(viewModel.list, viewModel.randomString)
    .map { (list, randomString) in list.map { (element: $0, randomString: randomString) } }
    .bind(to: tableView.rx.items(cellIdentifier: "cell")) {
        (index, model, cell) in
        cell.textLabel?.text = model.element + model.randomString
    }.disposed(by: disposeBag)