UICollectionView将图像添加到单元格

我正在使用UICollectionView来显示可能有或没有图像的数据的项目。

我使用的方式是检查图像的URL不是null,然后将一个ImageView添加到单元格。

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { if (question.picture != (id)[NSNull null]) { //add AsyncImageView to cell imageView.contentMode = UIViewContentModeScaleAspectFill; imageView.clipsToBounds = YES; imageView.tag = IMAGE_VIEW_TAG; [cell addSubview:imageView]; [[AsyncImageLoader sharedLoader] cancelLoadingImagesForTarget:imageView]; imageView.imageURL = [NSURL URLWithString:question.picture]; } } 

对于那些没有图像的单元格,单元格应该如下所示: https : //dl.dropboxusercontent.com/u/5753236/Stackoverflow/good.png

但是,他们中的一些仍然会添加一个带有裁剪图像的ImageView,导致如下所示: https : //dl.dropboxusercontent.com/u/5753236/Stackoverflow/bad.png

我试过使用SDWebImage,但仍然没有解决问题。

另一个问题是当我向下滚动UICollectionView ,会看到一些图像显示为上面显示的图像,然后在加载完成后切换到正确的图像,我不知道是什么导致了问题。

请帮我解决这两个问题,我真的很感激任何帮助。

首先,在单元中添加图像的方式非常危险。 原因是你的单元格正在被重用(例如,当你滚动,或当你reloadData),这些图像不会被重复使用删除。 所以你会开始把它们塞到你的地方,甚至可以达到你的单元格包含多次出现的图像的地步。 这里有两种方法来做到这一点:

  • 第一种方法(好的方法):你inheritance你的UICollectionViewCell,并给子类一个“imageView”属性。 然后你在你的CustomCollectionViewCell.m文件中这样做:

     // Lazy loading of the imageView - (UIImageView *) imageView { if (!_imageView) { _imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds]; [self.contentView addSubview:_imageView]; } return _imageView; } // Here we remove all the custom stuff that we added to our subclassed cell -(void)prepareForReuse { [super prepareForReuse]; [self.imageView removeFromSuperview]; self.imageView = nil; } 

    然后在你的ViewController中,你必须像这样声明你的collectionViewCells的新类:

     [self.collectionView registerClass:[CustomCollectionViewCell class] forCellWithReuseIdentifier:@"cell"]; 

    它将确保图像在重新使用时被正确删除,再加上它更容易在您的collectionView代理中设置单元格。

  • 第二种方法(肮脏的方式),你每次加载一个新的单元格时删除视图:

     - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { for (UIView *subview in [cell.contentView subviews]) { [subview removeFromSuperview]; } if (question.picture != (id)[NSNull null]) { //add AsyncImageView to cell imageView.contentMode = UIViewContentModeScaleAspectFill; imageView.clipsToBounds = YES; imageView.tag = IMAGE_VIEW_TAG; [cell.contentView addSubview:imageView]; [[AsyncImageLoader sharedLoader] cancelLoadingImagesForTarget:imageView]; imageView.imageURL = [NSURL URLWithString:question.picture]; } } 

    这种方式更容易,但我不会推荐它:P

现在试试这个,让我知道你的bug是如何演变的。