swiftuitableviewrx-swiftrx-cocoa

Problem with handling row selection with RxCocoa


I am studying RxCocoa for UITableView now. Everything works fine with presenting cells but when I add a closure to handle row selection a delay appears. I mean when I tap first row nothing happens, when I tap second row closure shows the reaction I expected for the first row, the third - for the second, etc... Please have a look at my code and help me fix the problem.

import RxCocoa
import RxRelay
import RxSwift
import UIKit

final class ListViewController: UITableViewController {
    
    private var todos = BehaviorRelay<[String]>(value: ["Clean the apt", "Learn to code", "Call mom", "Do the workout", "Call customers"])
    let bag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        title = "RxTodoList"
        tableView.dataSource = nil
        tableView.delegate = nil
        
        todos
            .bind(to: tableView.rx.items) { (tableView, row, element) in
                let cell = tableView.dequeueReusableCell(withIdentifier: "TodoCell")!
                cell.textLabel?.text = "\(element)"
                return cell
            }
            .disposed(by: bag)
        
        tableView.rx
            .modelDeselected(String.self)
            .asObservable()
            .subscribe(onNext: { [weak self] todo in
                print(todo)
            })
            .disposed(by: bag)
    }
    
}

Solution

  • You are using modelDeselected instead of modelSelected.

    Also, you should never have a Subject, Relay, or Observable as a var they should always be lets. So var todos = BehaviorRelay... should be let todos = BehaviorRelay...

    Lastly:

    The usage of subjects [and relays] should largely remain in the realms of samples and testing. Subjects are a great way to get started with Rx. They reduce the learning curve for new developers, however they pose several concerns...

    -- (IntroToRx)