After checking your project I suggest you use a slightly different approach.
After updating the model, you can ask the collection view layout what the new content size will be (collectionViewLayout.collectionViewContentSize). You then update the height constraint constant.
So, you should:
- update your model
- reload the row
- ask the layout for its new
contentSize
- update the height constraint constant
This modification in your project should achieve this:
// Remove the content size observing logic.
func configureForVehicle(_ vehicle: Vehicle, selectedHouseType: String) {
self.vehicle = vehicle
applianceCollectionView.reloadData()
// Set the height constraint to the new value, found in the layout's content size info.
// Since the model (self.vehicle) was already updated, the layout will return the new content size.
// Because this is all happening while the cell is being reloaded, the cell will also resize properly.
// You don't need to perform any other setNeedsLayout/layoutIfNeeded calls.
self.applianceCollectionViewHeightConstraint.constant = applianceCollectionView.collectionViewLayout.collectionViewContentSize.height
}
Note the comment about not needing any additional layout update calls. Only calling
tableView.reloadRows(at: [indexPath], with: .automatic)
should be enough. Unnecessary layout updates can cause a performance hit.
As a side note there is another approach you can use if you wish to animate the height change without reloading the cell. In this case you would need to keep/find a reference to the cell you wish to update then do the following:
- Update the model for the cell without calling any table view reload calls.
- Reload the collection view on the updated cell.
- Update the height constraint same way as above.
- Use a callback of some sort to notify your table view that a cell wishes to update its height.
- In the callback call
tableView.beginUpdates(); tableView.endUpdates()
. This causes the tableView to re-layout its cells and animate height changes.
From beginUpdates() documentation:
You can also use this method followed by the endUpdates() method to animate the change in the row heights without reloading the cell. This group of methods must conclude with an invocation of endUpdates().