2

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()
}
Rage
  • 870
  • 9
  • 27

2 Answers2

0

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.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • (I would suggest abandoning the use of `prepareForReuse`; personally I've never needed to use it for anything.) – matt May 06 '21 at 19:51
  • I know devs that use it and like that approach. Like you, I tend to instead fully configure cells in `tableView(_:cellForRowAt:)` – Duncan C May 06 '21 at 19:54
  • @DuncanC Yes, that's why that part is a comment and not part of the answer. – matt May 06 '21 at 19:56
  • All of my view configuration logic is inside of one cell class, can I use multiple reuse strings for the same class? – Rage May 06 '21 at 23:50
  • Yes, but that very question suggests you are a prisoner of your own architecture. You should rethink this. Isn’t this why we have subclasses? Protocols? Dependency injection? – matt May 07 '21 at 02:31
0

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.

Duncan C
  • 128,072
  • 22
  • 173
  • 272