Reputation: 145
I am working in xcode 8.3. I have a CollectionView. I have downloaded images from web sevice and placed the images in each CollectionView cells. But when i scrolling the CollectionView, images in the each cells are changing. After a few minutes it shows the correct image. I have tried many solutions available in stackoverflow. But i didnt get a solution. Please help me.
Upvotes: 3
Views: 3586
Reputation: 1
You can use prepareForReuse()
method to handle this issue.
override func prepareForReuse() {
super.prepareForReuse()
// still visible on screen (window's view hierarchy)
if self.window != nil { return }
imageView.image = nil
}
Notes: If you are using SDWebImage, you should add this line to cancel current cell image download.
imageView.sd_cancelCurrentAnimationImagesLoad()
Upvotes: 0
Reputation:
UICollectionView
reuses the same UICollectionViewCell
to improve performance. Only the data inside the UICollectionViewCell
is changed, so before using the UICollectionViewCell
, the UICollectionViewCell
has to be cleared of its previous data. Cocoa Framework
provides a method that is present in UICollectionViewCell
that triggers every time when the UICollectionViewCell
is to be reused.
just override the function given below in the .m file of your custom UICollectionViewCell
class file
-(void)prepareForReuse {
[super prepareForReuse];
// here we clear the previously set data
self.imageView.image = nil; // this will clear the previously set imageView is a property of UIImageView used to display a image data
}
Upvotes: 1
Reputation: 233
Like the others are saying its most likely because you are dequeuing reusable cells (As you should be) and setting the cell.imageView.image property to your web image.
The issue here is that because iOS is saving on memory by "reusing" these cells, they are literally the same cells in memory. So as it scrolls off one edge of the screen and disappears. As the new cell scrolls on instead of creating a new seperate cell it simply uses the one that it already has that just left the screen. Meaning your old image is still the one displayed in the cell.
Standard practice is setting the content of the cell in the cellForRowAtIndexPath:
method. But if you are setting it to an image that is fetched asynchronously its entirely possible(likely) for the cell to appear on the screen with the old image before the new one is fetched. Presumably once the images are downloaded its not so much of an issue anymore as they should return instantly from a cache.
The simple fix here would be to either nil out the image before setting it each time in the cell, or preferably use a placeholder image.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CELL_IDENTIFIER" forIndexPath:indexPath];
// This will clear any existing image from the cell about to be displayed it is an option
//[cell.imageView setImage:nil];
if (ImageExistsLocally)
{
cell.imageView.image = [UIImage imageWithContentsOfFile:@"SomeImagePath"];
}
else
{
[cell.cellImageView sd_setImageWithURL:yourRemoteImage.thumbnailUrl
placeholderImage:[UIImage imageNamed:PlaceHolderImageName]
completed:nil];
}
return cell;
}
Note that sd_setImageWithURL
is from the SDWebImage library that I think someone else mentioned here. https://cocoapods.org/pods/SDWebImage
Upvotes: 6
Reputation: 702
The problem you are facing is due to the Reuse of UITableViewCell. If you are downloading images from web service use AlamofireImage or SDWebImage. It will handle your problem.
Upvotes: 1
Reputation: 954
It is because of reusing cells. Try to reset the image in your cell class prepareForReuse method
-(void)prepareForReuse {
[super prepareForReuse];
self.imageView.image = nil;
}
Upvotes: 1