如何在异步图像下载和调整大小的图像高度后更新表视图单元格



如何使用翠鸟setImage with completion handler方法从服务器下载图像后更新单元格高度?图像下载后,我使用以下方法调整其高度约束的大小:cell.imageHeight.constant = image.size.height * cell.frame.size.width / image.size.width.

图像已下载并设置cellForRow方法上,但我也尝试了willDisplayCell,同样的问题。我还在setImage方法的完成处理程序中检查cell.tag == indexPath.row

我已经尝试了以下方法,但没有一种有效:

  • heightForRowUITableViewAutomaticDimension的,estimatedHeightForRowAt是某个值(最大可能的单元格(以及这两个的所有其他组合
  • 表视图开始/结束更新
  • reloadRowsat indexPath
  • cell.setNeedsLayoutlayoutIfNeededlayoutSubviews
  • dispatch main async

它们中的任何一个都会遇到相同的问题:滚动时跳跃的表格,首次显示时单元格高度错误,要更新它,我必须上下滚动以隐藏和显示该单元格,某些单元格上的表格视图计算的高度错误。

如果我滚动回顶部,一切都很好,因为所有图像都已经在缓存中。

大家是怎么做到的?Facebook或Instagram是如何做到这一点的?从任何 API 获取单元格高度后如何更新单元格高度?

您是否尝试过将以下内容添加到您的 viewDidLoad:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140

然后,无论您在哪里填充其他元素,您当然也需要调整这些元素的约束和高度。

我建议对单元格进行子类化,并为为其填充数据的单元格创建一个 set 方法。 这样,您可以调整单元格中元素的约束,以更好地处理填充它的数据。

我实际所做的和以某种方式工作的如下:

if (self.firstLoaded[indexPath.row] == false) {
self.firstLoaded[indexPath.row] = true
DispatchQueue.main.async {
self.tableViewController.tableView.reloadData()
}
}

firstLoaded只是告诉表,这一行已经从URL接收了图像并计算/存储了正确的高度。

另外,我使用了这个:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cellHeights[indexPath] = cell.frame.size.height
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if let height = cellHeights[indexPath] {
return height
}
return 1500
}

我知道调用 reloadData(( 不是一个好的做法,但它解决了我的问题。如果有人有其他建议,请不要犹豫,分享。

谢谢!

最新更新