编辑:https ://streamable.com/rfym将在行动中展示它。我第一次按滚动到底部时,它并没有一直到底部。然后我手动一直到底部并快速向上滚动。一旦我再次按下滚动到底部,它就可以正常工作,因为它正在使用缓存高度。
所以,我已经看到了很多答案,但似乎没有一个对我有用,我很确定这些对许多其他人也不起作用:
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)
}