我正在开发一个项目,该项目使用UICollectionView
来显示可能有或没有图像的数据。
我使用的方法是检查图像网址是否为空,然后将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
时,我会看到一些图像显示为上面显示的图像,然后在加载完成后更改为正确的图像,我只是不知道是什么导致了这个问题。
请帮我理清这两个问题,我真的很感激你的帮助。
答案 0 :(得分:14)
首先,在单元格中添加图像的方式非常危险。原因是您的单元格正在被重用(例如滚动时或重新加载数据时),这些图像在重用时永远不会被删除。因此,您将开始在任何地方进行搜索,甚至可以达到您的单元格包含多次图像的位置。这有两种方法:
第一种方式(好方法):你继承你的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是如何演变的。
答案 1 :(得分:1)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) var imageview:UIImageView=UIImageView(frame: CGRect(x: 50, y: 50, width: 200, height: 200)); var img : UIImage = UIImage(named:"Your image name") imageview.image = img cell.contentView.addSubview(imageview) } return cell } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: 50, height: 414) }