0

I want to call tableView.reloadData() and be sure that after that table rows are rendered. The problem is that not happening when I am setting datasource programmatically before that. Example:

class ViewController: UIViewController, UITableViewDataSource {
    @IBOutlet weak var tableView: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.reloadData()
        print("after reloadData")
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print("cellForRowAt")
        return UITableViewCell()
    }
}

Output is:

  1. print("after reloadData")
  2. print("cellForRowAt")

I expect it to print “cellForRowAt” first. Why is that happening?

Update: It's silly but I thought reloadData() was synchronous. What did the trick for me is: self.tableView.layoutIfNeezded() Thank you and thx this guy.

bauerMusic
  • 5,470
  • 5
  • 38
  • 53
RealNmae
  • 630
  • 9
  • 20
  • 1
    You are reloading the table before it is on screen, so it doesn't need to perform a rendering pass. Once the tableview is visible (After `viewDidLayoutSubviews`) it will need cells – Paulw11 Sep 25 '19 at 11:58
  • Well actually the call to the method tableView.reloadData() is asynchronous . Or more acurately methods like numberOfRows ,heightForRow gets calledUp first ,but CellForRowAtIndexPath doesnot. This is the reason why you see this behaviour. – Friend Sep 25 '19 at 12:09

1 Answers1

0

The function tableView.reloadData() is asynchronous it contains a patch of calls to dataSource methods in order until that happens you see the print first

Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87