I have a UITableView that I fill with autosizing cells.
UITableView
setup is fairly simple:tableView.estimatedRowHeight = 70
tableView.rowHeight = UITableViewAutomaticDimension
Exactly like Apple recommends here: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSelf-SizingTableViewCells.html
To enable self-sizing table view cells, you must set the table view’s rowHeight property to UITableViewAutomaticDimension. You must also assign a value to the estimatedRowHeight property. As soon as both of these properties are set, the system uses Auto Layout to calculate the row’s actual height.
When configuring a cell I also disable/enable some constraints to achieve the needed look. That’s where things get interesting. Cell layout is not updated until the cell is reused. Literally. You can call
layoutIfNeeded()
, setNeedsLayout()
, layoutSubviews()
or any other method there is, there is no way you will force the cell to update its layout.All other aspects work pretty good: labels do change their text, you hide/unhide the views, but layout is stuck until the cell is reused.
You can find the sample project with the bug here: https://www.dropbox.com/s/vqg0gw0a8ycziyq/ReusedCellBug.zip?dl=0
Question: what causes it and how to avoid this behavior?
P.S. After playing around I found out that if I completely remove `tableView.estimatedRowHeight = 70`, then layout works as expected, but trying to use autosizing cells without
estimatedRowHeight
leads to table view putting height constraint on cell's content view (height equals to 43.5 point). In error logs this constraint is the famous'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7fd63d508490.height == 43.5 (active)
And because my cell's height is not equal to 43.5 points, auto layout decides that this height constraint is more important than my cell's layout and fits my cell content in 43.5 points.
So I can't use
estimatedRowHeight
because it breaks auto layout, but without it my layout also gets broken.how can I safely deprioritize this
UIView-Encapsulated-Layout-Height
constraint? Is there any way I can get autosizing cells without using estimatedRowHeight
?