Ios UITableView:使用自定义/可变单元格高度滚动到底部在初始滚动时不准确
编辑:将在操作中显示它。我第一次按Scroll To Bottom时,它并没有一直按到底部。然后我手动进入底部,并快速向上滚动。一旦我再次按下Scroll To Bottom(滚动到底),它就会正常工作,因为它正在使用缓存权重。Ios UITableView:使用自定义/可变单元格高度滚动到底部在初始滚动时不准确,ios,swift,uitableview,uiviewcontroller,uitableviewautomaticdimension,Ios,Swift,Uitableview,Uiviewcontroller,Uitableviewautomaticdimension,编辑:将在操作中显示它。我第一次按Scroll To Bottom时,它并没有一直按到底部。然后我手动进入底部,并快速向上滚动。一旦我再次按下Scroll To Bottom(滚动到底),它就会正常工作,因为它正在使用缓存权重。 func scrollToBottom() { self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: self.replies.count - 1, inSection: 0), atScrollPo
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)
}
所以,我已经看到了很多答案,但没有一个对我有效,我很确定这些对其他很多人也不起作用:
tableView.setContentOffset(CGPointMake(0,CGFloat.max),动画:true)
:
砰的一声,瞬间,我的桌面视图消失了
tableView.setContentOffset(CGPointMake(0,self.tableView.contentSize.height-self.tableView.frame.size.height),动画:true)
:
不准确。它不会一直到底部。有时,它会超调
tableView.scrollToRowAtIndexPath(nsindepath(forRow:self.repries.count-1,第0节),atScrollPosition:.Bottom,动画:true)
同样,与前一个一样,这是不准确的
我知道为什么这是不准确的。我需要的是一个解决方案…
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)
}
下面是一些要运行的代码:
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.estimatedheightforrowatinedexpath
在初始滚动后工作正常
但是,如果我从不滚动到底部以缓存所有高度,并且我尝试通过编程方式滚动到底部,那么它就不会到达那里。为什么?因为我有tableView.estimatedheightforrowatinexpath
return 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)
}
这样,您的tableCell将重新定位,而不会出现您提到的错误
更新:(删除此功能)
我能看一下它发生的情况吗?只需访问makeagif.com。@JohnDoe检查我在顶部或此处包含的可流式链接:注意,我第一次按Scroll to Bottom时。。它不会一直走下去。然后,我手动进入底部。当我返回并再次按下按钮时,它成功地一直到底部。当视图出现时,您是否尝试过刷新所有内容?我从服务器异步加载数据,因此每当数据进入时都会重新加载。好的,您应该检查eddwinpaz是否回答了问题。看起来他明白了。只是在这里为那些不在聊天室的人迭代,但这不起作用(