重用 UICollectionView 中的单元格时,会短暂显示重用 UICollectionViewCell 的旧内容
Posted
技术标签:
【中文标题】重用 UICollectionView 中的单元格时,会短暂显示重用 UICollectionViewCell 的旧内容【英文标题】:The old contents of a reused UICollectionViewCell are briefly displayed when reusing cells in a UICollectionView 【发布时间】:2013-04-29 22:49:58 【问题描述】:我正在使用UICollectionView
来显示从 URL 异步加载的图片网格。我的收藏视图使用可重复使用的单元格来显示UICollectionViewCells
。未重用单元格时,所有内容都会正确显示,但是当我滚动一下时,重用的单元格会在开始正常行为之前短暂闪烁旧内容。
这里是自定义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
这里是自定义 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
【问题讨论】:
【参考方案1】:你可以在你的 UICollectionViewCell 子类中实现-(void)prepareForReuse
。并在那里进行重置。
【讨论】:
为什么这个投票比接受的答案多。这两个答案有什么区别吗? 这是 Apple 希望您在重置单元以准备重新使用时使用的方式。【参考方案2】:当单元格显示完毕后,您可以尝试将单元格的 URL 设置为 nil,它适用于我的项目。
-(void)collectionView:(UICollectionView *)cv didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
[(MyCollectionViewCell *)cell setUrlString:nil];
我希望这会有所帮助!
【讨论】:
【参考方案3】:This article 显示了@Weston 和@architectpianist 解决方案之间的区别。
简而言之:由于ios10 -(void)prepareForReuse
更优。
【讨论】:
以上是关于重用 UICollectionView 中的单元格时,会短暂显示重用 UICollectionViewCell 的旧内容的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell 中的 UICollectionView 重用