簡體   English   中英

UITableView:在初始滾動時,使用自定義/可變單元格高度滾動到底部是不准確的

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM