swift - TableView 计算错误的estimatedHeightForRowAt
问题描述
我正在制作一个类似应用程序的聊天应用程序,其中 tableView 显示动态高度单元格。
单元格的视图和子视图以正确的方式受到限制
这样AutoLayout 可以预测单元格的高度
(顶部、底部、前导、尾随)
但仍然- 正如您在视频中看到的那样 -滚动指示条显示计算了错误的高度:
当出现新行时,它会重新计算高度。
视频: https ://youtu.be/5ydA5yV2O-Q
(第二次尝试向下滚动一切都很好)
代码:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
这是一个简单的问题。有人可以帮我吗?
更新 1.0
添加了github:
解决方案
但仍然 - 正如您在视频中看到的那样 - 滚动指示条显示计算了错误的高度:
所以你想要的是精确的内容高度。
为此,您不能使用 static estimatedRowHeight
。您应该执行更正确的估计,如下所示。
...
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
}
这太精确(实际上是真实的行高)并且可能很慢,但是您可以进行更近似的估计以进行优化。
推荐阅读
- javascript - 这段代码可以重写为异步函数吗?
- .htaccess - 从 domainB.com 重定向到 domainA.com/subdirectory/ 后如何屏蔽子目录名称?
- android - Sceneform 无缝地将纹理应用于三角形
- angular - Angular 10 - 如何初始化一个类对象数组?
- css - 静态文件不能在cpanel上上传
- sql - 使用另一张表中的键将记录插入到一张表中
- java - 如何正确限制泛型接口以扩展 Java 中的 Number 类并能够在另一个类中运行它?
- python - Discord.py - 更改频道权限
- python - 如何为仅单个模块的库深处的monkeypatch方法?
- vue.js - 在 Vue 3 中安装 Jest 会在 Linux 上为 deasync 提供错误“无法找到绑定文件”