当调用scrollToRowAtIndexPath 时,不计算所有单元格的高度 b/w 当前位置和目标偏移量。只有其中一些是。
相反,UITableView 使用estimatedRowHeight 来计算导致错误偏移的目标偏移。
我遇到了同样的问题,我发现了一个小技巧(我不太喜欢)在初始 relaodData 之后只计算一次精确的单元格高度。我在下面插入了两行:
tableView.reloadData()
// only for the initial reloadData
let numSections = tableView.numberOfSections
let numRowsInLastSection = tableView.numberOfRowsInSection(numSections-1)
// scrolls to the last row in the tableView
tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: numRows-1, inSection: numSections-1), atScrollPosition: .Bottom, animated: false)
// back again to the original position(which is 0 for this is only called right after the initial reloadData)
tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: false)
这会导致 tableView 在屏幕上出现较晚,但我认为这是可以接受的,而不是在 tableView 出现后冻结 UI。在开始时调用 API 会更好,因为这感觉像是网络上的一点延迟,而不是 UI 延迟。
在此之后,tableView 会跳转到单元格的确切位置。
是的,我也不喜欢这个解决方案:|
编辑:
我这样做的唯一原因是通过调用cellForRowAtIndexPath: 来计算实际行高,但我发现当通过委托方法estimatedHeightForRowAtIndexPath: 为每一行提供适当的估计高度而不是给UITableView.estimatedRowHeight 提供静态值时解决了这个问题.
我最终所做的是将willDisplayCell:forRowAtIndexPath: 中的行高缓存到磁盘并在estimatedHeightForRowAtIndexPath: 上使用该值。
通过这样做,所有行的 estimatedHeightForRowAtIndexPath: 都会在开始时被调用,scrollToRowAtIndexPath 运行良好。