How to prepareForReuse on a UITableView with auto-layout?

571 Views Asked by At

I have have a UITableView with cells of automatic dimension using auto-layout. In addition, all of the subviews of the cells are using auto-layout (programmatic constraints).

Since these cells and their corresponding subviews have uniquely different sizes, when they are reused, the constraints for the cell and subviews do not seem to invalidated and reset and this results in the following:

Demonstration of problem:

Without reuse With reuse

I have tried all sorts of things in the prepareForReuse function but I haven't been able to reset all constraints. How can this be achieved?

Something I tried:

override func prepareForReuse() {
    super.prepareForReuse()
    
    invalidateIntrinsicContentSize()
    removeConstraints(constraints)
    subviews.forEach( { $0.removeConstraints($0.constraints); $0.invalidateIntrinsicContentSize()  })
    
    
    setNeedsUpdateConstraints()
}
2

There are 2 best solutions below

5
On BEST ANSWER

This sort of situation is why there are multiple reuse buckets. Use a different cell subclass / reuse string for each type of cell. That way, there is nothing to do: just set up the cell once and let autolayout take care of resizing when, say, the text is different or (for an image cell) the image is different.

0
On

I would advise against deleting all your constraints and rebuilding them when getting a cell ready for reuse. Instead, I would add outlets to your constraints, and then either update their constants to change their sizing/spacing, or have them divided into sets for your different use-cases and use activate(_:) and deactivate(_:) to turn the different sets of constraints on/off. (Or a combination of adjusting constants and turning some constraints on and off.

It might also be simpler to set up different types of cells using different identifiers, and just set the constraints up on each type of when you create those cells. I'd make this my first choice, in fact.