动态更改UITableViewCell高度 - Swift 4?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (618)

如何动态更改UITableViewCellHeight?我试过实现以下内容,但由于某种原因它无法正常工作。加载显示此tableview的视图控制器后代码崩溃

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let cell = tableView.cellForRow(at: indexPath) as! AvailableRideCell
    return cell.getHeight()
}

这是getHeight我的功能AvailableRideCell

func getHeight() -> CGFloat {
    return self.destinationLabel.optimalHeight + 8 + self.originLabel.optimalHeight + 8 + self.priceLabel.optimalHeight
}

这就是optimalHeight功能

extension UILabel {
var optimalHeight : CGFloat {
    get
    {
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude))
        label.numberOfLines = 0
        label.lineBreakMode = NSLineBreakMode.byWordWrapping
        label.font = self.font
        label.text = self.text
        label.sizeToFit()
        return label.frame.height
    }
}
提问于
用户回答回答于

您因此行编码崩溃

let cell = tableView.cellForRow(at: indexPath) as! AvailableRideCell

Apple Documentation我们知道此方法用于优化。整个想法是获得细胞高度而不浪费时间来创建细胞本身。所以这个方法初始化任何单元格之前调用,然后tableView.cellForRow(at: indexPath)返回nil。因为还没有任何细胞。但你正在用力展开,as! AvailableRideCell你的代码崩溃了。

所以首先,您需要了解,为什么不应该在cellForRow(at )方法中使用任何单元格。之后,您需要更改逻辑,以便在不调用单元格的情况下计算内容高度。

例如,在我的项目中,我使用了这个解决方案

extension String {
    func height(for width: CGFloat, font: UIFont) -> CGFloat {
        let maxSize = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
        let actualSize = self.boundingRect(with: maxSize,
                                           options: [.usesLineFragmentOrigin],
                                           attributes: [NSAttributedStringKey.font: font],
                                           context: nil)
        return actualSize.height
    }
}

有了它,您需要做的就是计算标签并存储其字体。

var titles = ["dog", "cat", "cow"]

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // number of rows is equal to the count of elements in array
    return titles.count
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let cellTitle = titles[indexPath.row]
    return cellTitle.height(forWidth: labelWidth, font: labelFont)
}

动态行高度变化

如果您需要更新行高,您需要做的就是在更改内容时调用此方法。indexPath是已更改项的索引路径。

tableView.reloadRows(at: [indexPath], with: .automatic)

希望它能帮到你。

用户回答回答于

请记住,UITableViewCell可以重复使用。因此获得当前单元格的高度可能不稳定。

更好的方法是使用一个假/占位符单元格(我称之为计算器单元格)并使用它来计算单元格的大小。

因此,在heightForRowAt方法中,您获取数据而不是单元格。将该数据放入计算器单元格中并从那里获取高度。

扫码关注云+社区

领取腾讯云代金券