@Skywalker 答案的 Swift 5 变体:
private var heightDictionary: [IndexPath: CGFloat] = [:]
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
heightDictionary[indexPath] = cell.frame.size.height
}
public func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
let height = heightDictionary[indexPath]
return height ?? UITableView.automaticDimension
}
另一个解决方案(从 MessageKit 获取):
应该调用此方法而不是reloadData
. 这可以适用于特定情况。
extension UITableView {
public func reloadDataAndKeepOffset() {
// stop scrolling
setContentOffset(contentOffset, animated: false)
// calculate the offset and reloadData
let beforeContentSize = contentSize
reloadData()
layoutIfNeeded()
let afterContentSize = contentSize
// reset the contentOffset after data is updated
let newOffset = CGPoint(
x: contentOffset.x + (afterContentSize.width - beforeContentSize.width),
y: contentOffset.y + (afterContentSize.height - beforeContentSize.height))
setContentOffset(newOffset, animated: false)
}
}