TableView calculates wrong estimatedHeightForRowAt
You need to set tableFooterView
to empty.
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
// your staff
}
But still - as you can see in the video - the scroll indicator bar shows that wrong heights were calculated:
So what you want is precise content height.
For that purpose, you cannot use static estimatedRowHeight
.
You should implement more correct estimation like below.
...
var sampleCell: WorldMessageCell?
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "WorldMessageCell", bundle: nil), forCellReuseIdentifier: "WorldMessageCell")
sampleCell = UINib(nibName: "WorldMessageCell", bundle: nil).instantiate(withOwner: WorldMessageCell.self, options: nil)[0] as? WorldMessageCell
}
...
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if let cell = sampleCell {
let text = self.textForRowAt(indexPath)
// note: this is because of "constrain to margins", which value is actually set after estimation. Do not use them to remove below
let margin = UIEdgeInsets(top: 8, left: 20, bottom: 8, right: 20)
// without "constrain to margins"
// let margin = cell.contentView.layoutMargins
let maxSize = CGSize(width: tableView.frame.size.width - margin.left - margin.right,
height: CGFloat.greatestFiniteMagnitude)
let attributes: [NSAttributedString.Key: Any]? = [NSAttributedString.Key.font: cell.messageLabel.font]
let size: CGRect = (text as NSString).boundingRect(with: maxSize,
options: [.usesLineFragmentOrigin], attributes: attributes, context: nil)
return size.height + margin.top + margin.bottom
}
return 100
}
This is too precise (actually real row height) and maybe slow, but you can do more approximate estimation for optimization.