快速滚动时,CollectionViewCell显示错误的图像

时间:2018-10-04 23:51:14

标签: ios swift uicollectionview

我知道人们以前曾问过这个问题,但是我实现代码的方式似乎有点不同,因为我使用的是单元格标签。我对其他一切如何加载感到非常满意,然后当我滚动太快时图像抖动并且不正确。我该如何解决这个问题?

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

        if let activity = cell.viewWithTag(103) as? UIActivityIndicatorView {
            activityMain.isHidden = true
            activityMain.stopAnimating()
            activity.isHidden = false
            activity.startAnimating()

        }

        DispatchQueue.main.async {
        if let pageLabel = cell.viewWithTag(101) as? UILabel {
            pageLabel.text = self.Networking.fetchedPagesNumbers.reversed()[indexPath.row]
            }
        }

        if let image = cell.viewWithTag(100) as? UIImageView {

            image.image = UIImage(named: "Rectangle")

            DispatchQueue.global(qos: .background).async {
                do{
                    let data = try Data.init(contentsOf: URL.init(string:self.Networking.fetchedPagesURLs.reversed()[indexPath.row])!)

                    DispatchQueue.main.async {

                        let imageToCache = UIImage(data: data)!

                        imageCache.setObject(imageToCache, forKey: self.Networking.fetchedPagesURLs.reversed()[indexPath.row] as NSString )

                        image.image = imageToCache

                            if let activity = cell.viewWithTag(103) as? UIActivityIndicatorView {
                                activity.isHidden = true
                                activity.stopAnimating()
                                collectionView.isScrollEnabled = true
                            }
                    }
                }
                catch {
                    // error
                }
            }
        }
        return cell
    }

3 个答案:

答案 0 :(得分:1)

1-代替标签

if let activity = cell.viewWithTag(103) as? UIActivityIndicatorView {

通过强制转换单元格为单元格自定义类中的每个UI元素创建IBOutlet

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PageCell", for: indexPath) 
 as! PageCell

2-不需要

中的DispatchQueue.main.async
DispatchQueue.main.async {
 if let pageLabel = cell.viewWithTag(101) as? UILabel {

cellForRowAt的代码默认在主队列中运行

3-不用做繁重的图像下载工作。使用缓存 SDWebImage

image.sd_setImage(with: URL(string:self.Networking.fetchedPagesURLs.reversed()[indexPath.row])!), placeholderImage: UIImage(named: "placeholder.png"))

答案 1 :(得分:1)

在collectionViewCell类中,您应该覆盖prepareForReuse()

override func prepareForReuse() {
    super.prepareForReuse()

    self.pageLabel.text = nil
    self.imageView.image = UIImage()
}

答案 2 :(得分:1)

在图像缓存方面,我建议 Kingfisher https://github.com/onevcat/Kingfisher

非常容易使用:

let url = URL(string: "url_of_your_image")
imageView.kf.setImage(with: url)