UITableViewAutomaticDimension
will estimate the cell size depending on cells content size. We must calculate the max height that a cell could possibly have, and return this height for all cells instead of using UITableViewAutomaticDimension
.
CustomTableViewCell
let kMargin: CGFloat = 8.0
class CustomTableViewCell: UITableViewCell {
@IBOutlet var singleLineLabel: UILabel!
@IBOutlet var doubleLineLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
updateFonts()
}
override func prepareForReuse() {
updateFonts()
}
func updateFonts() {
singleLineLabel.font = UIFont.preferredFont(forTextStyle:.title3)
doubleLineLabel.font = UIFont.preferredFont(forTextStyle:.body)
}
func updateCellForCellWidth(_ width:CGFloat) {
doubleLineLabel.preferredMaxLayoutWidth = width - (2*kMargin)
}
func fillCellWith(_ firstString: String, _ secondString: String) {
singleLineLabel.text = firstString
doubleLineLabel.text = secondString
}
}
On View Controller
Setting up a dummy cell and listing to notifications for dynamic type
var heightCalculatorDummyCell: CustomTableViewCell!
var maxHeight: CGFloat = 0.0
override func viewDidLoad() {
super.viewDidLoad()
heightCalculatorDummyCell = tableView.dequeueReusableCell(withIdentifier: "cell_id") as! CustomTableViewCell
maxHeight = getMaxHeight()
NotificationCenter.default.addObserver(self, selector: #selector(AutomaticHeightTableViewController.didChangePreferredContentSize), name: .UIContentSizeCategoryDidChange, object:nil)
}
Getting max height using a dummy cell.
func getMaxHeight() -> CGFloat {
heightCalculatorDummyCell.updateFonts()
heightCalculatorDummyCell.fillCellWith("Title","A string that needs more than two lines. A string that needs more than two lines. A string that needs more than two lines. A string that needs more than two lines. A string that needs more than two lines.")
heightCalculatorDummyCell.updateCellForCellWidth(tableView.frame.size.width)
let size = heightCalculatorDummyCell.contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
return (size.height + 1)
}
Handling Table view reloads on notification
deinit {
NotificationCenter.default.removeObserver(self)
}
func didChangePreferredContentSize() {
maxHeight = getMaxHeight()
tableView.reloadData()
}
Final step, returning max heights in tableview delegate
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titles.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return maxHeight
}
![enter image description here]()