![](/img/trans.png)
[英]reloadData of UITableView with Dynamic cell heights unwanted scroll
[英]UITableView: Scrolling to the bottom with custom/variable cell heights is inaccurate on the initial scroll
编辑: https : //streamable.com/rfym将显示它的实际效果。 我第一次按下Scroll To Bottom,它并没有一直到底。 然后我手动一直到底部并快速向后滚动。 一旦我再次按下Scroll To Bottom,它就能正常工作,因为它正在使用cachedHeights。
所以,我已经看到了很多这方面的答案,但它们似乎都不适合我,我很确定这些也不适用于其他许多人:
tableView.setContentOffset(CGPointMake(0, CGFloat.max), animated: true)
:
砰的一声,我的tableView消失了。
tableView.setContentOffset(CGPointMake(0, self.tableView.contentSize.height - self.tableView.frame.size.height), animated: true)
:
不准确的。 它并没有一直到底。 有时它会超调!
tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: self.replies.count - 1, inSection: 0), atScrollPosition: .Bottom, animated: true)
同样,与前一个一样,这是不准确的。
我知道为什么这是不准确的。 我需要的是一个解决方案......
以下是一些要运行的代码:
class RepliesTableViewController: UITableViewController {
var cachedHeights = [Int: CGFloat]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
self.cachedHeights[indexPath.row] = cell.frame.size.height
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if let height = cachedHeights[indexPath.row] {
return height
} else {
return 113
}
}
}
请记住, 只有初始滚动到底部并不是一直都是这样 。 如果我用手指一直向下滚动到底部,然后向上滚动到顶部并触发滚动到底部,这将是完美的。
原因很简单:我将在每个单元格上触发tableView.willDisplayCell
,这意味着所有高度都已缓存 。 这意味着tableView.estimatedHeightForRowAtIndexPath
在初始滚动后完美运行。
但是,如果我从不滚动到底部来缓存所有高度,我尝试以编程方式滚动到底部,它将无法到达那里。 为什么? 因为我有tableView.estimatedHeightForRowAtIndexPath
返回113。
有些人可能会说我需要更准确的估计,但我拒绝接受这种想法。 我的细胞可以小到50,大到5000. 没有准确的估计 。
我该如何缓解这种情况?
也许我需要在不同的时间缓存所有高峰? 现在几点了? 我不想对自己做任何计算。 tableView.willDisplayCell
的美妙之处在于我可以缓存cell.frame.size.height
而不是自己繁琐的计算。
编辑2:我有一个搞笑的解决方案......这是非常笨重的...而且是不可接受的......但从技术上讲它是有效的。 适合娱乐。
func scrollToBottom() {
self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: self.replies.count - 1, inSection: 0), atScrollPosition: .Bottom, animated: true)
}
override func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {
if !atBottom {
self.tableView.setContentOffset(CGPointMake(0, tableView.contentOffset.y + 200), animated: true)
}
}
override func scrollViewDidScroll(scrollView: UIScrollView) {
atBottom = scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)
}
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 113.0; // set to whatever your "average" cell height is
这样你的tableCell将重新定位,而不会提到你提到的不准确性
更新:(删除此功能)
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if let height = cachedHeights[indexPath.row] {
return height
} else {
return 113
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.