1

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.

Anjali Shah
  • 720
  • 7
  • 21
Thasian
  • 57
  • 1
  • 1
  • 7
  • Did you add your tableView to any view attached to the window? – Subramanian Mariappan Dec 02 '19 at 06:39
  • check if you have imported RXCocoa on top. second the bind methods will be called when menuitems will get updated. If that doesnot work declare your dataModel (menuItems ) as a behaviourRelay like this - let menuItems: BehaviorRelay<[String]> = BehaviorRelay(value: ["Recommended", "Dashboard", "Settings"]) – Help Dec 02 '19 at 06:59
  • how do you add your tableview to the view-controller ? if your tableview doesn't get appear , bind function wont get executed – Arvin Rezaei Dec 02 '19 at 07:00
  • I've solved my problem. Turns out I didn't set the bottom constraint of my tableview, which caused it to not be displayed. And since it wasn't displayed, the data source items were never set. – Thasian Dec 02 '19 at 15:01

1 Answers1

2

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.

Thasian
  • 57
  • 1
  • 1
  • 7