Search code examples
iosswiftxcodereactiverxdatasources

Tableview data isn't being set while using RxSwift


I am creating my tableview programmatically

extension UITableView {
static var tableView: UITableView {
     let tableView = UITableView()
     tableView.register(UITableViewCell.self, forCellReuseIdentifier: "menuCell")
     tableView.translatesAutoresizingMaskIntoConstraints = false
     return tableView
    }
}

I am calling a binding function during viewdidload

private func setUpBindings() {
    guard let viewModel = self.viewModel else { return }

    viewModel.menuItems
        .bind(to: tableView.rx.items(cellIdentifier: "menuCell", cellType: UITableViewCell.self)) { [weak self] row, model, cell in
            Logger.info("Called")
            cell.selectionStyle = .none
            cell.textLabel?.text = model.uppercased()
            cell.textLabel?.textColor = self?.selectedRow == row ? .white : .darkGray
            cell.backgroundColor = self?.selectedRow == row
                ? ColorPreference.mainColor
                : UIColor.clear
        }
        .disposed(by: self.disposeBag)
        self.tableView.reloadData()
}

The datasource for my tableview is from an observable in my viewmodel

let menuItems = Observable.just([
    "Recommended",
    "Dashboard",
    "Settings"
])

The problem I'm having is that the bind function isn't being called for the tableview. There are clearly items in the observable that should be bound but every possible test I've done has never executed the body of the tableview binding.

To confirm my theory, I tested this code within setupBindings() and the body of it was executed, printing out "2019-12-01 16:36:18 | INFO | ["Recommended", "Dashboard", "Settings"]"

viewModel.menuItems
        .bind(onNext: { items in
            Logger.info("\(items)")
        })
        .disposed(by: self.disposeBag)

I've looked at the documentation for properly settings tableview's datasource and have done my fair share of research. I'm stumped and need help.


Solution

  • Really silly error. Before I fixed it, my tableview constraints looked like this

    self.tableView.topAnchor.constraint(equalTo: appLabel.bottomAnchor, constant: 30).isActive = true
    self.tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
    self.tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
    

    I forgot to set the bottom constraint of the tableview to its superview. From what I could extrapolate, this prevented the tableview from being shown in the view. Without it being shown, it isn't possible to set the data source of the tableview, as pointed out by Arvin in the comments.