[英]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.