UITableViewCell layout not updating until cell is reused

Solution 1:

Unfortunately, none of the provided answers/comments worked out for me. I always ended up with an initially incorrect layout. Only after reusing the cell, or calling reloadData() (on the table view) it was displayed correctly.

The following was the only thing, that worked for me in the end. I'm not a big fan of such hacks, but after spending about half a day on this seemingly very simple layout issue, I just gave up and went with it. >.<

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    DispatchQueue.main.async {
        self.tableView.reloadData()
    }
}

Alternatively you could also call reloadData it in viewDidAppear (without the DispatchQueue hack), but then you can clearly see the "jump" when the layout jumps from "incorrect" to "correct".

Anyway, just wanted to share my experience and hope this helps someone else. Cheers!

Solution 2:

I had your problem too. Instead of remove

tableView.estimatedRowHeight = 70

I just added a layoutIfNeeded at the end of the cellForRow method, just before return the cell itself:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "identifier", for: indexPath) as? MyCustomCell
    ...
    cell?.layoutIfNeeded()
    return cell!
}

Result: the cell layout is perfect always, the first time and every after reuse.

Solution 3:

In my case, the issue was caused by estimatedRowHeight.

Simply removing this line

tableView.estimatedRowHeight = 70

fixed my problems. Cell properly updated its layout and it almost fixed my issues.

But, most likely, you’re going to get another trouble, with your cell’s height being set to 43.5 points. You log will also be filled with auto layout errors, that will include a line like this

<NSLayoutConstraint:0x600000097570 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7fd4ee511d20.height == 43.5   (active)>

Apparently, if you won’t provide estimatedRowHeight, table view puts a 43.5 points height constraint on your cell’s content view, and if your cell’s “internal” height will not match (and probability of that is 99.99%), then it’s going to put errors in log.

How to avoid that error? I don’t know yet. I post a question about that, and as soon as I find an answer, I will provide a link in this question.