【发布时间】:2018-11-28 19:14:10
【问题描述】:
我有一个UITableView,它显示带有图像和一些文本的单元格。数据是按需请求的——我首先请求 10 行的数据,然后再请求下 10 行的数据,依此类推。我在tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 中执行此操作。问题是当我收到数据并需要更新tableview 时,它有时会跳跃和/或闪烁。我打电话给reloadData。以下是部分代码:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
DispatchQueue.global(qos: .background).async {
if indexPath.row + 5 >= self.brands.count && !BrandsManager.pendingBrandsRequest {
BrandsManager.getBrands() { (error, brands) in
self.brands.append(contentsOf: brands as! [Brand])
DispatchQueue.main.async {
UIView.performWithoutAnimation {
self.brandsTableView.reloadData()
}
}
}
}
}
}
单元格的高度是恒定的,返回如下:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 70
}
我正在使用 Kingfisher 下载和缓存图像。以下是来自数据源的更多代码:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return brands.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiers.ImageTableCell, for: indexPath) as! ImageTableViewCell
let brand = brands[indexPath.row]
cell.centerLabel.text = brand.brand
cell.leftImageView.image = nil
if let url = BrandsManager.brandLogoURL(forLogoName: brand.logo!) {
let resource = ImageResource(downloadURL: url, cacheKey: url.absoluteString)
cell.leftImageView.kf.setImage(with: resource)
} else {
print("Cannot form url for brand logo")
}
return cell
}
如何避免滚动时表格视图的闪烁和跳跃?我查看了一些类似的问题,但找不到适合我的案例的有效解决方案。
【问题讨论】:
-
不止几件事可以做到这一点。其中之一是使用估计行高不匹配的自动尺寸。您可能需要创建高度缓存以避免它。但总的来说,请尝试添加更多关于您正在做什么的信息
-
@MaticOblak 感谢您的回复。细胞的高度是恒定的。我更新了我的问题。
-
如果您使用的是故事板/界面构建器,请关闭单元格的自动尺寸。
-
仍然只是尝试添加estimatedRowHeight方法并返回70。或者,我相信您可以将其设置为表格视图上的属性。问题是,当您向下滚动并调用重新加载数据时,系统仍会尝试优化并调用估计高度而不是真实高度。默认情况下,我相信估计的高度是 44,所以表格视图可能会跳跃。 (这可能是其他事情,但如果您首先确保不是这种情况,我真的更喜欢)。
-
@MaticOblak 感谢您的建议和解释。提供
estimatedHeightForRow与heightForRow相同时,跳跃消失了。闪烁仍然存在,并由 Josh Homann 建议使用.automatic动画而不是reloadData调用`UITableView.insertRows(at:with:)` 修复。如果您将您的评论作为答案,我会投赞成票,但我会将整个解决方案作为单独的答案提供并接受它以明确起见。
标签: ios swift uitableview flicker