5

There is a TableView with Cells and there is ImageView in each of them. I use SDWebImage to load images and it works fine, but when I scroll fast - I see that images in cells are changing few times before it will be right image.

Why is it happening? What should I do?

p.s. I tried use it with or without placeholder with same result

imageView.sd_setImage(with: URL(string : myImageURL), placeholderImage: UIImage(named: "default.jpg"))
moonvader
  • 19,761
  • 18
  • 67
  • 116

4 Answers4

5

In your prepareForReuse() try adding:

imageView.sd_cancelCurrentImageLoad()

It will cancel the previous image downloading and then it won't happen.

Also, I would suggest using the sd_setImage with the completion block, that way you can also make sure it loads correctly.

unkgd
  • 671
  • 3
  • 12
  • What can you recommend to check in this completion block? – moonvader Feb 12 '17 at 09:12
  • usually I add a fade animation to make the image appear more smoothly, when you add a fade-in transition to the image, users don't notice when you have hard image transitions, sometimes I also checked if the image matches the object (object was cleared upon a private initializer in the cell itself). But also SDWebImage's method with completion block works better. – unkgd Feb 12 '17 at 09:25
4
// This will prevent sdwebimage load wrong url
guard let imgUrl = "Your image url.jpg" else { return }
imageView.sd_setImage(with: URL(string: imgUrl), placeholderImage: UIImage(named: "Your placeholder image.png"))


// Or you can match the url using this code, so the downloader won't catch the wrong url
if imgUrl == "Your image url" {
    imageView.sd_setImage(with: URL(string: imgUrl), placeholderImage: UIImage(named: "Your placeholder image.png"))
}


// This is will clean your UIImageView, and cancel download progress when cell is not visible (will reuse)
class YourCell: UITableViewCell {
    override prepareForReuse() {
        imageView.sd_cancelCurrentImageLoad()
        imageView.image = nil
    }
}
miken32
  • 42,008
  • 16
  • 111
  • 154
1

Firstly, you can use placeholder image of SDWebImage.

imageView.sd_setImage(with: URL(string: "http://www.domain.com/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))

Secondly, you can clean image when cell was reused.

class YourCell: UITableViewCell {
    override prepareForReuse() {
        // sample code
        imageView.image = nil
    }
}
Lumialxk
  • 6,239
  • 6
  • 24
  • 47
  • I tried to combine both methods that you suggest, but when I scroll fast - I still see that images are changing few times – moonvader Feb 12 '17 at 08:11
  • @moonvader I wonder how many times did you set the image for one cell. – Lumialxk Feb 12 '17 at 08:17
  • In cellForRowAt of my table I run function getImage(imageView: cell.ImageView, item_id: id) it takes imageview and id of item that it should find image for, after this it uses sd_setImage to load image to this imageview – moonvader Feb 12 '17 at 08:26
0

Use

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! NewsTableViewCell

Instead of

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! NewsTableViewCell

Hope it will solve Your problem. It is repeating because of reusability of Cell

vp2698
  • 1,783
  • 26
  • 28
  • While your diagnosis is correct, this is not a solution to the problem. Cell reuse is a great optimisation technique so you should instead try to work with it, not around it. – Balázs Vincze May 03 '21 at 22:10