当我插入新行时,UITableView 正在跳跃
Posted
技术标签:
【中文标题】当我插入新行时,UITableView 正在跳跃【英文标题】:UITableView is jumping when I insert new rows 【发布时间】:2018-03-14 18:33:27 【问题描述】:我尝试了很多方法来解决这个问题,但我做不到。我的tableView
在加载更多数据后会跳转。我在willDisplay
调用下载方法:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
let lastObject = objects.count - 1
if indexPath.row == lastObject
page = page + 1
getObjects(page: page)
并在此处插入行:
func getObjects(page: Int)
RequestManager.sharedInstance.getObjects(page: page, success: objects in
DispatchQueue.main.async(execute:
self.objects = self.objects + objects
self.tableView.beginUpdates()
var indexPaths = [IndexPath]()
for i in 0...objects.count - 1
indexPaths.append(IndexPath(row: i, section: 0))
self.tableView.insertRows(at: indexPaths, with: .bottom)
self.tableView.endUpdates()
);
)
那我做错了什么?为什么tableView
插入新行后会跳转?
【问题讨论】:
【参考方案1】:我刚刚找到了停止跳表视图的解决方案 在表视图中插入多行。我正面临这个问题 最近几天,所以我终于解决了这个问题。
我们只需要设置表格视图的内容偏移量,而 在表格视图中插入行。你只需要传递你的数组 IndexPath 休息你可以使用这个功能。
希望这个方法对你有帮助。
func insertRows()
if #available(ios 11.0, *)
self.tableView.performBatchUpdates(
self.tableView.setContentOffset(self.tableView.contentOffset, animated: false)
self.tableView.insertRows(at: [IndexPath], with: .bottom)
, completion: nil)
else
// Fallback on earlier versions
self.tableView.beginUpdates()
self.tableView.setContentOffset(self.tableView.contentOffset, animated: false)
self.tableView.insertRows(at: [IndexPath], with: .right)
self.tableView.endUpdates()
【讨论】:
这个解决方案对我有用,现在我的 tableview 不再跳跃了! 太棒了,它也帮助了我【参考方案2】:tableView
也有类似的问题。部分原因是我用beginUpdates() 和endUpdates() 决定的
self.tableView.beginUpdates()
self.tableView.endUpdates()
但这并没有解决问题。 对于 iOS 11,问题仍然存在。 我添加了一个包含所有单元格高度的数组,并在方法 tableView(_:heightForRowAt:)
中使用了这些数据func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return cellHeights[indexPath.row] ?? 0
同样添加这个方法tableView(_:estimatedHeightForRowAt:)
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
return cellHeights[indexPath.row] ?? 0
在那之后,跳跃停止了。
【讨论】:
谢谢,现在跳得少了。但它仍然跳...我想要 Instagram 应用程序如何加载更多单元格... 我用 tableView(:estimatedHeightForRowAt:) 更新了我的答案。这很奇怪,但是 tableView (:estimatedHeightForRowAt :) 帮助我彻底摆脱了这个问题。 在哪里为 cellHeights 添加高度? 我在 CustomTable VieCell 类中进行高度计算。我总结了所有垂直约束,所有标签高度,视图高度...... 在文档中它说“使用 -performBatchUpdates:completion: 代替这些方法 (beginUpdates),这些方法将在未来的版本中弃用。”【参考方案3】:首先,检查您的tableView(_:estimatedHeightForRowAt:)
- 这永远不会准确,但单元格高度越可能以这个估计值结束,表格视图所做的工作就越少。
因此,如果您的表格视图中有 100 个单元格,那么您确定其中 50 个单元格最终的高度将为 75 - 这应该是估计值。
另外值得一提的是,表格视图可以向其代表询问确切单元格高度的次数没有限制。因此,如果您有一个包含 1000 行的表格视图,那么单元格之外的布局就会出现很大的性能问题(延迟以秒为单位) - 实施估计会大大减少这些调用。
您需要重新审视单元格设计的第二件事,是否有任何视图或控件的高度需要由表格视图计算?就像具有顶部和底部锚点的图像等价于其他视图,其高度从一个单元格到另一个单元格?
这些视图/控件的固定高度越多,表格视图就越容易布局其单元格。
我在两个表格视图中遇到了同样的问题,其中一个有一个可变高度的图像嵌入到堆栈视图中,我必须在其中实现估计。另一个没有固定大小的图像,我不需要执行估计来使其平滑滚动。 两个表视图都使用分页。
最后但同样重要的是,数组是结构。结构是值类型。所以也许你不想在数组中存储任何高度,看看你正在制作多少份?
计算tableView(_:heightForRowAt:)
内部的高度非常快速和高效,足以很好地计算出来。
【讨论】:
【参考方案4】:因为您的循环从 0 运行到对象计数:
for i in 0...objects.count - 1
indexPaths.append(IndexPath(row: i, section: 0))
索引路径为第 0 行生成计数,直到对象计数。因此这些行被添加到表的顶部(即在第 0 行),因此导致表视图跳转,因为您在表视图的底部。
尝试将范围更改为:
let rangeStart = self.objects.count
let rangeEnd = rangeStart + (objects.count - 1)
for i in rangeStart...rangeEnd
indexPaths.append(IndexPath(row: i, section: 0))
希望对你有帮助..!!!
【讨论】:
以上是关于当我插入新行时,UITableView 正在跳跃的主要内容,如果未能解决你的问题,请参考以下文章