Previous contents of a reusable UICollectionViewCell are briefly displayed when reusing cells in a UICollectionView

I am using UICollectionView to display a grid of images that are loaded asynchronously from URLs. My collection view uses reuse cells to display UICollectionViewCells . Everything displays correctly when cells are not reused, but when I scroll a bit, reused cells flash briefly with the old contents before they start normal behavior.

Here is the implementation of a custom UICollectionViewController :

 #import "MyCollectionViewViewController.h" #import "MyCollectionViewCell.h" @interface MyCollectionViewViewController () @property (strong, nonatomic) NSArray *data; @end @implementation MyCollectionViewViewController @synthesize data = _data; - (void)viewDidLoad { [super viewDidLoad]; self.data = @[ @"http://s3-ec.buzzfed.com/static/enhanced/webdr01/2013/1/18/12/enhanced-buzz-wide-851-1358529670-4.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr03/2013/1/18/11/enhanced-buzz-wide-26311-1358526816-5.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr03/2013/1/18/11/enhanced-buzz-wide-26311-1358527190-11.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr02/2013/1/18/11/enhanced-buzz-wide-7517-1358526694-11.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr03/2013/1/18/11/enhanced-buzz-wide-1965-1358527802-7.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr03/2013/1/18/11/enhanced-buzz-wide-2165-1358527708-14.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr03/2013/1/18/11/enhanced-buzz-wide-1965-1358527894-12.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr02/2013/1/18/12/enhanced-buzz-wide-15957-1358529198-18.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr02/2013/1/18/12/enhanced-buzz-wide-16520-1358528981-9.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr02/2013/1/18/12/enhanced-buzz-wide-16517-1358529292-5.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr01/2013/1/18/12/enhanced-buzz-wide-20349-1358529323-20.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr01/2013/1/18/12/enhanced-buzz-wide-32444-1358529959-9.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr01/2013/1/18/12/enhanced-buzz-wide-32343-1358530043-7.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr02/2013/1/18/12/enhanced-buzz-wide-23646-1358530321-2.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr01/2013/1/18/12/enhanced-buzz-wide-28223-1358530801-15.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr01/2013/1/18/12/enhanced-buzz-wide-32273-1358530695-16.jpg", @"http://s3-ec.buzzfed.com/static/enhanced/webdr01/2013/1/18/12/enhanced-buzz-wide-31288-1358531103-16.jpg" ]; [self.collectionView registerNib:[UINib nibWithNibName:@"MyCollectionViewCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"myView"]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { NSString *urlString = [self.data objectAtIndex:indexPath.item]; MyCollectionViewCell *myView = [collectionView dequeueReusableCellWithReuseIdentifier:@"myView" forIndexPath:indexPath]; myView.urlString = urlString; [myView setNeedsDisplay]; return myView; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return CGSizeMake(150, 150); } - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.data.count; } @end 

Here is an implementation of a custom UICollectionViewCell.

 #import "MyCollectionViewCell.h" #import <QuartzCore/QuartzCore.h> #import <AVFoundation/AVFoundation.h> @interface MyCollectionViewCell () @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end @implementation MyCollectionViewCell @synthesize urlString = _urlString; + (void)loadAsyncImageFromURL:(NSString *)urlString withCallback:(void (^)(UIImage *))callback { NSURL *url = [NSURL URLWithString:urlString]; dispatch_queue_t downloadQueue = dispatch_queue_create("com.example.downloadqueue", NULL); dispatch_async(downloadQueue, ^{ NSData * imageData = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:imageData]; dispatch_async(dispatch_get_main_queue(), ^{ callback(image); }); }); } -(void) fadeInView:(UIView *)view WithSecondDuration:(double)duration { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; animation.beginTime = 0; animation.duration = duration; animation.fromValue = [NSNumber numberWithFloat:0.0f]; animation.toValue = [NSNumber numberWithFloat:1.0f]; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeBoth; animation.additive = NO; [view.layer addAnimation:animation forKey:@"opacityIN"]; } - (void) setUrlString:(NSString *)urlString { _urlString = urlString; self.imageView.image = nil; self.imageView.layer.opacity = 0; if (urlString) { [MyCollectionViewCell loadAsyncImageFromURL:urlString withCallback:^(UIImage *image) { self.imageView.image = image; [self fadeInView:self.imageView WithSecondDuration:.25]; }]; } } @end 
+6
source share
3 answers

You can try setting the cell url to zero, when the cell finished displaying, it worked on my project.

 -(void)collectionView:(UICollectionView *)cv didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath { [(MyCollectionViewCell *)cell setUrlString:nil]; } 

Hope this helps!

+5
source

You can implement -(void)prepareForReuse in your subclass of UICollectionViewCell. and do your dump there.

+18
source

This article shows the difference between @Weston and @architectpianist solutions.

In short: since iOS10 -(void)prepareForReuse more optimal.

+1
source

Source: https://habr.com/ru/post/943927/


All Articles