UITableView - cell images changing while scrolling

You are reusing old cells, which is a good thing. However, you are not initializing the image in the cell's image view, which is not such a good thing. What you're describing happens because an old cell, with an image that was already loaded for that cell, is used for the new cell. You are then loading that cell's image in the background (which, again, is good) but it takes a few moments for that image to fully load. In the meantime, the image that was already loaded on the old cell, is displayed (and that's the reason you're seeing a wrong image in that cell, for a few moments).

The solution? add either

thumbnailImageView.image = nil

or

thumbnailImageView.image = someDefaultImageWhileYourRealOneLoads

right before dispatch_queue_t concurrentQueue ....

That way, you won't see the old (irrelevant) image while the real one loads.

I hope this helps. Good luck.


I would do all my data binding at - tableView:willDisplayCell:forRowAtIndexPath: only because at cellForRowAtIndexPath your cell hasn't been drawn yet. Another solution you can use is AFNetworking like someone else mentioned before me.


As becauase your ImageView is being loaded in an async dispatch call which is NOT on the main thread and is being called in some other thread so there is a delay in fetching the data from the URL and then converting it to an UIImage. THis process takes a bit of time as you know but you are scrolling the tableview in a faster rate. And as you know cellForRowAtIndexPath reuses any cell that is out of the window so the cell that is being reused might NOT fetched the imagedata that it WAS TO RETRIEVE previously when it was in the Window. Thus it loads the wrong data and then again when async is fired for that specific cell the cell loads that image but there comes the delay.

To overcome this feature as Chronch pointed it out u can leave the imageview as nil OR you can use AFNetworking's own UIImageView catagory which has a superb class to load imageview images quite elegantly

I'll leave u a link to it AFNetworking


You can try adding following code to your cellForRowAtIndexPath -

1) Assign an index value to your custom cell. For instance,

cell.tag = indexPath.row

2) On main thread, before assigning the image, check if the image belongs the corresponding cell by matching it with the tag.

dispatch_async(dispatch_get_main_queue(), ^{
    if(cell.tag == indexPath.row) {
      UIImage *tmpImage = [[UIImage alloc] initWithData:imgData];
      thumbnailImageView.image = tmpImage;
    }});
 });