簡體   English   中英

第一個TableView單元未正確出隊

[英]First TableView cells are not dequeuing properly

我正在使用該應用程序,該應用程序使用https://www.countryflags.io/ API將標志加載到類中。 使用Alamofire get請求初始化對象時,我正在加載標志。 問題在於,啟動應用程序時出隊的前幾個TableView單元格沒有標記。

但是當我向下滾動后向后滾動時,它們會完美加載。

我以為是因為沒有足夠快地處理請求,並且在開始出隊單元之前沒有准備好加載第一個標志。 但是我不知道如何在getFlag()方法中設置一些東西來幫助我在完成時重新加載TableView數據,或者延遲出隊到加載所有標志時的延遲。

使用getflag()方法的國家/地區類別

import UIKit
import Alamofire

final class Country {
    let name: String
    let code: String
    var flag: UIImage?
    var info: String?

    init(name: String, code: String, flag: UIImage? = nil, info: String? = nil) {
        self.name = name
        self.code = code
        if flag == nil {
            getFlag()
        } else {
            self.flag = flag
        }
        self.info = info
    }

    func getFlag() {
        let countryFlagsURL = "https://www.countryflags.io/\(code.lowercased())/shiny/64.png"

        Alamofire.request(countryFlagsURL).responseData { response in
            if response.result.isSuccess {
                if let data = response.data {
                    self.flag = UIImage(data: data)
                }
            }
        }
    }
}

cellForRowAt方法

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let country = countries[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "Country", for: indexPath)

        cell.textLabel?.text = country.name
        if let flag = country.flag {
            cell.imageView?.image = flag
        } else {
            cell.imageView?.image = .none
        }

        return cell
    }

Countryinit方法不應啟動異步圖像檢索。 相反,您應該讓cellForRowAt啟動異步圖像檢索。

但是,您也不應該只是異步地更新cell (因為在Alamofire請求完成時該行可能已經被重用)。 而且,更微妙的一點是,如果快速滾動到表視圖的末尾,您將希望避免積壓圖像請求,因此您想取消對不再可見的行的待處理請求。 有多種方法可以實現所有這三個目標(在cellForRowAt異步圖像檢索,不要在將單元格用於另一行之后更新單元格,並且如果快速滾動,不要讓其積壓)。

最簡單的方法是使用AlamofireImage 然后,處理異步圖像請求,取消對重用單元的請求等所有這些復雜性都將降低為:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: “Country", for: indexPath)
    cell.imageView.af_setImage(withURL: objects[indexPath.row].url, placeholderImage: placeholder)
    return cell
}

注意,如果您要使用默認的表格視圖單元格,則建議您在此例程中提供一個占位符圖像,如上所示。 只需創建一個與您的標志大小相同的空白圖像(或其他任何圖像)即可。 這樣可以確保正確放置單元。


順便說一句,如果您想以編程方式生成該占位符圖像,則可以執行以下操作:

let imageSize = CGSize(width: 44, height: 44)

lazy var placeholder: UIImage = UIGraphicsImageRenderer(size: imageSize).image { _ in
    UIColor.blue.setFill()
    UIBezierPath(rect: CGRect(origin: .zero, size: imageSize)).fill()
}

現在,這將創建一個44×44的藍色占位符縮略圖,但是您可以根據自己的應用調整顏色和大小。

暫無
暫無

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

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