2

When I scrolling table view, the tableViewCell's image keep change incorrect image.

I tried this.

@IBOutlet weak var imageView: UIImageView!

override prepareForReuse() {
    super.prepareForReuse()

    self.imageView.image = nil
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? MyCustomCell else { return UITableViewCell() }
    cell.tag = indexPath.row
    if cell.tag == indexPath.row {
        // download image
        downloadManager.download { (image) in
            cell.imageView.image = image
        }
    }
}

But, this still incorrect image when scrolling. How can I fix it??

oddK
  • 261
  • 4
  • 14

3 Answers3

3

once you downloaded the image (async) you need to check that your cell is actually related to that image.

eg. cell may be reused for another indexPath so image downloaded is not correct anymore.

I have added index (indexPath.row) to download completion closure so you can check if the cell.tag is equals to index

downloadManager.download(index: indexPath.row) { (image, index) in
    if cell.tag == index {
    cell.imageView.image = image
    }
}
RJE
  • 781
  • 6
  • 14
1

You can set a placeholder image to fix this issue. Please use https://github.com/onevcat/Kingfisher for async image loading

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

Here is working code to Download and load image from URL with Display placeholder image upto load the actual image with NSCache.

https://stackoverflow.com/a/51746517/10150796

Nikunj Kumbhani
  • 3,758
  • 2
  • 26
  • 51
Tarun M
  • 46
  • 3
1

Try this:

import UIKit

class CustomViewCell: UITableViewCell {

@IBOutlet weak var imageView: UIImageView!

private var task: URLSessionDataTask?

override func prepareForReuse() {
    super.prepareForReuse()
    task?.cancel()
    imageView.image = nil
}

func configureWith(url string: String) {
    guard let url = URL(string: string) else { return }

    task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        if let data = data, let image = UIImage(data: data) {
            DispatchQueue.main.async {
                self.imageView.image = image
            }
        }
    }
    task?.resume()
 }
}
  • 1
    your code should be accompanied of an explanation. Just throwing it like this will not help OP understand hiw problem – Crocsx Nov 30 '19 at 04:12