I created expandable UITableViewCell class that modifies constaint to achieve the effect.
import UIKit
class ExpandableCell: UITableViewCell {
@IBOutlet weak var img: UIImageView!
@IBOutlet weak var imgHeightConstraint: NSLayoutConstraint!
var isExpanded:Bool = false
{
didSet
{
if !isExpanded {
self.imgHeightConstraint.constant = 0.0
} else {
self.imgHeightConstraint.constant = 128.0
}
}
}
}
View Controller
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 21
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:ExpandableCell = tableView.dequeueReusableCell(withIdentifier: "ExpandableCell") as! ExpandableCell
cell.img.image = UIImage(named: imgs[indexPath.row])
cell.isExpanded = false
return cell
}
// TableView Delegate methods
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(indexPath.row)
guard let cell = tableView.cellForRow(at: indexPath) as? ExpandableCell
else { return }
UIView.animate(withDuration: 0.3, animations: {
let offset: CGPoint = self.tableView.contentOffset
tableView.beginUpdates()
cell.isExpanded = !cell.isExpanded
self.tableView.layer.removeAllAnimations()
self.tableView.setContentOffset(offset, animated: false)
tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.top, animated: true)
tableView.endUpdates()
})
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? ExpandableCell
else { return }
UIView.animate(withDuration: 0.3, animations: {
tableView.beginUpdates()
cell.isExpanded = false
tableView.endUpdates()
})
}
Everything works fine for the few first rows, after scroll down, cells are not behaving properly, seems like it scrolls to the top, then the image dissapears.
I know it might have something to do with not storing boolean isExpanded
value in some array to keep track of it, but nonetheless I guess it's something wrong with refreshing the TableView.
EDIT
Sulthan answer helped me a lot, but the problem with scrolling to the top especially when tapping the lowest cells keeps persisting.
Tried this UITableView scrolls to top when reloading cells with changing cell heights
with estimatedRowHeight to the closest value but it does not solve my issue in case of expandable cells.
Anybody got an idea how to fix it?