Well this turned out trickier than I expected.
Here's how I implemented it. I am not really sure if this is a good way or not so take it with a grain of salt. Find link to the project below.
You need to know two things:
- The default/normal cell height (which is basically the estimated height of cell).
- Increase in height of cell after the view has been added to the cell (in my example I have taken the height to be 200).
When you tap on a button which is supposed to add the subview you call a completion handler passing the indexPath
and heightToBeAdded
(200 in this example) as parameters.
The completion will look something like this:
self.indexPath = iPath
self.cellHeight = self.defaultCellHeight + heightToBeAdded
UIView.beginAnimations("aaa", context: nil)
UIView.setAnimationDuration(1)
self.tableView.beginUpdates()
self.tableView.reloadRows(at: [iPath], with: .none)
self.tableView.endUpdates()
UIView.commitAnimations()
if heightToBeAdded > 0.0 {
self.addCellSubviews()
}
The iPath
is the same indexPath that you sent a parameter. The cell height is calculated from the two things I have described above.
When endUpdates()
calls the delegate and datasource methods would encounter the following method:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
guard let iPath = self.indexPath else { return UITableViewAutomaticDimension }
if indexPath == iPath {
return cellHeight
}
else {
return UITableViewAutomaticDimension
}
}
This will increase the cell height. But what about the actual subview that needs to be added?
For that we have addCellSubviews()
which is actually a completion block that is executed inside the UITableViewCell subclass. Call this only after end updates because by that time cell height will be calculated properly.
let yView = UIView()
yView.backgroundColor = .yellow
yView.translatesAutoresizingMaskIntoConstraints = false
self.addAsSubview(sView: yView)
NSLayoutConstraint.activate([
yView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 8),
yView.topAnchor.constraint(equalTo: self.topAnchor, constant: 8),
yView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -275),
yView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -8)
])
UIView.animate(withDuration: 1, animations: {
self.layoutIfNeeded()
})
Here is the result -

Link to the project
Please note there are some caveats(like tapping one cell closes the other) which I am sure you will be able to work out.