簡體   English   中英

將Aync Gif加載到滾動CollectionView

[英]Loading Aync Gifs to Scrolling CollectionView

在我的GIF從取Giphy API正確的回報,實際上正確加載到uicollectionview使用SwiftGif

僅當我立即滾動時,問題才uicollectionviewuicollectionview加載重復的gif或索引不正確的gif。 我了解這可能是一個延遲渲染gif並將gif加載到單元格的時間問題。

任何指導將不勝感激,因為異步操作是我仍然不熟悉的東西。

如果下面的代碼中有任何標志,特別是為了支持速度/內存使用,則任何處理gif的最佳做法也將不勝感激。

我嘗試進行各種檢查,例如查看最初傳遞的gif URL在加載時是否相同,並且每次觸發cellForItemAt都將圖像設置為nil,但無濟於事。 找不到現有的線程也可以清楚地解決此問題。

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

@IBOutlet weak var gifCollectionView: UICollectionView!

var gifUrls: [String] = []
var gifImages: [String: UIImage] = [:]

func fetchGiphs() {
    let op = GiphyCore.shared.search("dogs", media: .sticker) { (response, error) in

        guard error == nil else {
            print("Giphy Fetch Error: ", error)
            return
        }

        if let response = response, let data = response.data, let pagination = response.pagination {
            for result in data {
                if let urlStr = result.images?.downsized?.gifUrl {
                    self.gifUrls.append(urlStr)
                }
            }
            if !self.gifUrls.isEmpty {
                DispatchQueue.main.async {
                    self.gifCollectionView.reloadData()
                }
            }
        } else {
            print("No Results Found")
        }
    }
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return gifUrls.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! GifCell

    let passedUrlString = gifUrls[indexPath.item]
    cell.imageView.image = nil

    if let image = gifImages[gifUrls[indexPath.item]] {
        DispatchQueue.main.async {
            cell.imageView.image = image
            cell.activityIndicator.isHidden = true
        }
    } else {
        cell.activityIndicator.isHidden = false
        cell.activityIndicator.startAnimating()
        DispatchQueue.global(qos: .default).async {
            let gifImage = UIImage.gif(url: self.gifUrls[indexPath.item])
            DispatchQueue.main.async {
                if passedUrlString == self.gifUrls[indexPath.item] {
                    cell.activityIndicator.stopAnimating()
                    cell.activityIndicator.isHidden = true
                    cell.imageView.image = gifImage
                    self.gifImages[self.gifUrls[indexPath.item]] = gifImage
                }
            }
        }
    }

    return cell
}
}


class GifCell: UICollectionViewCell {
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
}

如您所知,完成圖像加載后,該單元可能會被重用。

您需要檢查它是否被重用。 您的passedUrlString == self.gifUrls[indexPath.item]不適用於此目的。

也許,為每個單元格提供一個唯一的ID將起作用:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! GifCell
    let uniqueId = Int.random(in: Int.min...Int.max) //<-practically unique
    cell.tag = uniqueId //<-

    cell.imageView.image = nil

    if let image = gifImages[gifUrls[indexPath.item]] {
        cell.imageView.image = image
        cell.activityIndicator.isHidden = true
    } else {
        cell.activityIndicator.isHidden = false
        cell.activityIndicator.startAnimating()
        DispatchQueue.global(qos: .default).async {
            let gifImage = UIImage.gif(url: self.gifUrls[indexPath.item])
            DispatchQueue.main.async {
                if cell.tag == uniqueId { //<- check `cell.tag` is not changed
                    cell.activityIndicator.stopAnimating()
                    cell.activityIndicator.isHidden = true
                    cell.imageView.image = gifImage
                    self.gifImages[self.gifUrls[indexPath.item]] = gifImage
                }
            }
        }
    }

    return cell
}

假設您沒有將tag用於其他目的。

請試試。

暫無
暫無

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

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