TableView计算错误的estimatedHeightForRowAt

Kár*_*rás 8 scrollview tableview swift

我正在进行类似应用程序的聊天,其中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
}
Run Code Online (Sandbox Code Playgroud)

这是一个简单的问题.有人可以帮我吗?

更新1.0

添加了github:

https://github.com/krptia/Test

tak*_*aka 4

但是,正如您在视频中看到的,滚动指示条仍然显示计算出错误的高度:

所以你想要的是精确的内容高度。

为此,您不能使用 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
    }

Run Code Online (Sandbox Code Playgroud)

这太精确了(实际上是真实的行高)并且可能很慢,但是您可以进行更近似的估计以进行优化。