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是如何演变的。