ios - UICollectionView 将图像添加到单元格

标签 ios uiview uiimage uicollectionview uicollectionviewcell

我正在开发一个项目,该项目使用 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 时,我会看到一些图像先显示为上图,然后在加载完成后更改为正确的图像,我只是不知道是什么导致了问题。

请帮我解决这两个问题,非常感谢您的帮助。

最佳答案

首先,您在单元格中添加图像的方式非常危险。原因是您的单元格正在被重复使用(例如,当您滚动或重新加载数据时),并且这些图像在重复使用时永远不会被删除。所以你会开始到处看到它们,你甚至可以到达你的单元格包含多次出现的图像的地步。这里有两种方法:

  • 第一种方法(好的方法):将 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 委托(delegate)中设置单元格也更加容易。

  • 第二种方式(肮脏的方式),每次加载新单元格时都会删除 View :

    - (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

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

关于ios - UICollectionView 将图像添加到单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23801418/

相关文章:

ios - 在代码中为 topLayoutGuide 和 bottomLayoutGuide 创建自动布局约束

iphone - Restkit 覆盖本地实体更改

objective-c - UIView 的 frame origin 和 size 是只读的背后的逻辑是什么

ios - 如何让UIView停止接收触摸事件?

iphone - 如何根据屏幕分辨率获取 UIimage 大小

ios - 将按钮限制为 UIImageView 内的图像

ios - 步骤:Add the Push Notifications feature to your App ID报错

iphone - Flipboard 或 iBooks 风格的动画

ios - 旋转 UIImage 的问题 - IOS/Swift

ios - iPad 1,使用30针VGA线