簡體   English   中英

強制 UITableView 緩存可重用的單元格

[英]Force UITableView to cache reusable cells

我使用帶有相對“重”自定義表格視圖單元格的表格視圖 - 假設單個單元格(完整層次結構)中有大約 100 個子視圖。 盡管如此,我已經能夠實現非常平滑的滾動 - 使用標准做法,例如僅使用不透明視圖、隱藏未使用的子視圖(甚至從視圖層次結構中刪除)、預加載單元格高度等。

問題是創建單個單元格實例的成本仍然相對較高。 由於標准 UITableView 的單元格重用邏輯的工作方式,此問題僅在特定條件下才會明顯。

通常當加載表格視圖(並顯示初始內容)時,它會創建幾乎所有必需的單元格實例 - 因此當您開始滾動時,它很少需要創建更多可重用的單元格。 但是如果由於某種原因它在開始時只顯示幾個單元格,它顯然需要在啟動滾動時創建更多單元格。 在我的情況下,如果有一個寬的表格視圖標題或者第一個單元格足夠大,這很明顯。 當您開始滾動時發生這種情況時,會出現片刻明顯的延遲,這顯然是由正在創建的新單元格實例引起的。 沒有什么特別難看的,但仍然很明顯,尤其是與之后的絕對平滑滾動相比。

現在顯而易見的解決方案是讓單元格“更輕”——比如將它們分成不同的更具體的類型,這樣每個類型都可以包含更少的子視圖。 但是由於我的內容的組織方式,這將是一個非常復雜的解決方案。

所以我的問題是 - 有沒有什么好方法可以“欺騙”表視圖邏輯來立即強制加載和緩存特定數量的可重用單元格實例 - 盡管實際可見的單元格數量?

我一直在考慮的選項之一是擁有自己的單元格顯式緩存,並在需要時用單元格預先填充它(例如在 -viewDidLoad 中)。 我使用這種方法的問題是您必須事先知道您需要的確切細胞類型 - 對我來說效果不佳。 改進將是在加載初始數據時構建緩存(因此至少知道內容的確切類型)但我一直想知道是否有任何簡單的選項。

您可以通過將您自己的“二級緩存”層添加到您的數據源來實現。

初始化數據源時,根據需要預先創建盡可能多的單元格,並將它們放入一個數組中。 當您的dequeueReusableCellWithIdentifier失敗時,首先選擇該數組,然后從那里取出一個單元格。 陣列用完后,開始創建新單元格(如果您預先創建了足夠多的單元格,則不需要即時創建新單元格:當您有足夠多的單元格旋轉進出可見性時,出列最終會停止失敗)。

我也有類似的情況,我想在不同的單元格中加載多個網站,並且必須只觸發一次 loadrequest。 想法是通過向上或向下滾動使單元格可見/不可見時避免重復調用。 假設我的 tableview 中有 5 個單元格,每個單元格都有一個加載不同網站的 webview。 loadrequest 將被調用一次並且單元格將被緩存。 這是最簡單的實現。

變量聲明

let weblinks:[String] = ["http://www.google.com",
                         "http://www.facebook.com",
                         "http://www.yahoo.com",
                         "http://www.puthiyathalaimurai.com/",
                         "http://www.github.com"]
var mycells:[MyTableViewCell] = [MyTableViewCell(),
                                 MyTableViewCell(),
                                 MyTableViewCell(),
                                 MyTableViewCell(),
                                 MyTableViewCell()]

單元格換行。 我希望你知道它的作用,

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellIdentifier = String(describing: MyTableViewCell.self)

    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as? MyTableViewCell
    if cell?.isNewCell == true { //return from cache
        return mycells[indexPath.row]
    }
    cell?.title.text = weblinks[indexPath.row].uppercased()
    cell?.web.loadRequest(URLRequest(url: URL(string: weblinks[indexPath.row])!))
    cell?.isNewCell = true //mark it for cache
    mycells[indexPath.row] = cell!
    return cell!
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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