Swift UITableViewCell-如果我向下滚动得太快,则单元格图像会更改,但仅限于第一次尝试

时间:2019-05-26 16:13:33

标签: swift uitableview

我正在我的viewDidLoad方法中解析一个JSON。 JSON中的关键之一是图像URL,它进入一个名为“ allCImages”的字符串数组中

这只是一个字符串。因此,要将图像填充到单元格中,在cellForRowAt方法中,我具有以下内容:

cell.vcCellImage.downloadImage(from: allCImages[indexPath.section])

注意:vcCellImage是我的单元格图像视图的IBOutlet。

“ downloadImage”方法是以下扩展程序的一部分:

extension UIImageView {
    func downloadImage(from imgURL: String!) {
        let theUrl = URLRequest(url: URL(string: imgURL)!)

        // set initial image to nil so it doesn't use the image from a reused cell
        image = nil

        // check if the image is already in the cache
        if let imageToCache = vc1ImageCache.object(forKey: imgURL! as NSString) {
            self.image = imageToCache
            print("Image is in Cache")
            return
        }

        // download the image asynchronously 
        let task = URLSession.shared.dataTask(with: theUrl) { (data, response, error) in
            if error != nil {
                print(error!)
                return
            }

            DispatchQueue.main.async {
                // create UIImage
                let imageToCache = UIImage(data: data!)
                // add image to cache
                vc1ImageCache.setObject(imageToCache!, forKey: imgURL! as NSString)
                self.image = imageToCache
            }
        }

        task.resume()
    }

这几乎可以正常工作。例如:

1)如果我缓慢向下滚动表格视图,则所有单元格都包含正确的图像

2)如果我缓慢或快速向上滚动表格视图,则所有单元格都包含正确的图像。我的控制台正在打印以下内容,这证明了这一点:

  • 图像在缓存中
  • 图像在缓存中
  • 图像在缓存中

即,tableview正在从缓存中获取我的图像(因为要向上滚动,所以我之前必须先向下滚动)

3)问题是,如果我第一次尝试时真的快速向下滚动了表格视图。由于图像尚未缓存,因此该单元将显示错误的图像,然后再更改为正确的图像。经典问题

因此,我缺少了这一小段逻辑。该如何解决?


编辑:我尝试过这个,但是问题仍然存在:

  • VCTableViewCell类:UITableViewCell {

    覆盖函数func prepareForReuse(){     super.prepareForReuse()     vcCellImage.image =无 }

3 个答案:

答案 0 :(得分:1)

这是由于

1-单元出队:在tableView内部重复使用单元

2-当您在请求发生之前滚动时,可能会导致新的1带有相同的

最佳选择是使用SDWebImage

答案 1 :(得分:0)

我也遇到过类似的问题。 我已通过取消 prepareForReuse 方法中的图像请求来解决此问题。 你可以试试吗?

答案 2 :(得分:0)

首先,如果要添加api或类似的任何数据,只需将其删除

var arr = [string]()

viewDidLoad()
{
arr.append("s","sd","sd)
}

接受

var arr = [string]()

viewWillAppear()
{
arr.removeAll()
//call api
//append Data
arr.append("s","sd","sd)
}

我有类似的问题,然后我这样解决,也许对您也有帮助。