iOS - 图像未加载到可重用的 UICollectionViewCell 上
Posted
技术标签:
【中文标题】iOS - 图像未加载到可重用的 UICollectionViewCell 上【英文标题】:iOS - Images not loading on reusable UICollectionViewCell's 【发布时间】:2012-11-26 10:06:07 【问题描述】:您好,我有一个问题,如果可能的话,我将不胜感激。我有一个应用程序,它有一个 UICollectionView,它使用一个内部有一个 UIImageView 的 UICollectionViewCell。每次使用适当的图像生成单元格时,都应该设置此图像视图。但是图像不会出现,如果我在图像视图上使用我试图设置的图像数据执行 initWithImage,但每次重用单元格时,新的图像视图都会保留在那里。
代码如下:
@interface collectionViewController : UICollectionViewController
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
@property (strong, nonatomic) NSMutableArray *imageURLs;
@end
@interface collectionViewController ()
@property (strong, nonatomic) UIImage *cachedImage;
@end
@implementation collectionViewController
@synthesize imageURLs = _imageURLs; @synthesize cachedImage =_cachedImage;
- (void)viewDidLoad
[super viewDidLoad]; // Do any additional setup after loading the view.
// Register reusable cell for controller
[self.collectionView registerClass:[collectionViewCell class] forCellWithReuseIdentifier:@"Image Cell"];
//Set url for images
_imageURLs = [@[@"http://www.bestcssvault.com/installation/wpcontent/themes/cssvault/gallery/2012/02/daniel_designer-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2012/02/595x400hngry-265x180.png",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2012/02/licron-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2012/02/media-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2012/02/alio-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2012/02/zdravkomecava-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2011/12/guidepiscine_dot_com-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2011/12/web6-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2011/12/CSSVault_Transics-thumb-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2011/12/screen3-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2011/12/divaoffice595x400-265x180.jpg",
@"http://www.bestcssvault.com/installation/wp-content/themes/cssvault/gallery/2011/12/screenshot-265x180.jpg"] mutableCopy];
-(NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView
return 1;
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
return _imageURLs.count;
-(collectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
static NSString *cellIdentifier = @"Image Cell";
collectionViewCell *imageCollectionCell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
int row = [indexPath row];
if(imageCollectionCell.imageCollectionView) NSLog(@"worked at %d", row);
//Get Image Data
NSURL * imageURL = [NSURL URLWithString:_imageURLs[row]];
dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL);
dispatch_async(downloadQueue, ^
NSData * imgData = [NSData dataWithContentsOfURL:imageURL];
dispatch_async(dispatch_get_main_queue(), ^
UIImage * imageCompleted = [UIImage imageWithData:imgData];
imageCollectionCell.inspirationImage = imageCompleted;
//imageCollectionCell.imageCollectionView.image = imageCompleted;
//NSLog(@"width = %f, height = %f", imageCompleted.size.width, imageCompleted.size.height);
);
);
imageCollectionCell.backgroundColor = [UIColor grayColor]; //dispatch_release(downloadQueue);
return imageCollectionCell;
@end
@interface collectionViewCell : UICollectionViewCell
@property (weak,nonatomic) IBOutlet UIImageView *imageCollectionView;
@property (weak,nonatomic) UIImage *inspirationImage;
@end
@implementation collectionViewCell
@synthesize imageCollectionView =_imageCollectionView;
@synthesize inspirationImage = _inspirationImage;
-(void)setImageCollectionView:(UIImageView *)imageCollectionView
//imageCollectionView = [[UIImageView alloc] initWithFrame:self.frame];
//[self.contentView addSubview:imageCollectionView];
if(!_imageCollectionView)
_imageCollectionView = imageCollectionView;
_imageCollectionView.image = _inspirationImage;
-(void)setInspirationImage:(UIImage *)inspirationImage
if(!_inspirationImage)
_inspirationImage = inspirationImage;
//_imageCollectionView.image = inspirationImage;
self.imageCollectionView.image = _inspirationImage;
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
// Initialization code
self.backgroundColor = [UIColor whiteColor];
return self;
- (void)prepareForReuse
[super prepareForReuse];
//_inspirationImage = [[UIImage alloc] init];
/* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
// Drawing code
*/
@end
任何帮助将不胜感激:)
【问题讨论】:
【参考方案1】:问题出在 UIImageView 中。如果 ImageView 在呈现单元格时没有图像,则在设置图像时不会显示。有2个解决方案。 1)创建单元格时设置默认图像。
static NSString *cellIdentifier = @"Image Cell";
collectionViewCell *imageCollectionCell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImage * placeholderImage = [UIImage imageNamed:@"placeholder"];
imageCollectionCell.inspirationImage = placeholderImage;
2) 更新图像后在单元格上调用 setNeedsLayout。
dispatch_async(dispatch_get_main_queue(), ^
UIImage * imageCompleted = [UIImage imageWithData:imgData];
imageCollectionCell.inspirationImage = imageCompleted;
[cell setNeedsLayout];
【讨论】:
我已经尝试实现你的方法,但我仍然只得到一个灰色的 UICollectionViewCell,还有其他想法吗?非常感谢您的帮助:) 这很奇怪,因为我已经在我的 UItableViewController 上测试了这段代码。我使用标准 UITableViewCell 和旧实现来获取可重用单元格。所以也许这是个问题 我认为 UITableViewController 上的测试与这种情况无关。你的意思是因为一次又一次地重复使用相同的视图,我没有这个问题的表视图但是每次我使用collectionview时我都会一次又一次地遇到同样的问题。如果你愿意,我可以把 tableview 和 collectionview 的项目发给你。【参考方案2】:我有另一种方法。
先将图片异步下载到另一个图片数据数组中。
然后在-collectionView:cellForItemAtIndexPath:
中,检查该图像是否已下载(如果尚未下载,则设置为 nil;已下载的将 nil 替换为图像数据)
如果已下载,则设置图像,否则设置为另一个“默认”图像。
您可能还需要引用图像视图,以便在下载图像时更新图像。
【讨论】:
我也试过这个,将图像设置为 nil 使它不会出现在视图中,我必须做一个 alloc init 让它工作,这是迄今为止唯一的方法但它非常不可靠且效率低下。任何其他想法将不胜感激。以上是关于iOS - 图像未加载到可重用的 UICollectionViewCell 上的主要内容,如果未能解决你的问题,请参考以下文章