【问题标题】:UICollectionView adding image to a cellUICollectionView 将图像添加到单元格
【发布时间】:2014-07-11 04:07:20
【问题描述】:

我正在做一个项目,该项目使用UICollectionView 来显示可能有也可能没有图像的数据。

我使用的方式是检查图片url是否不为空,然后在单元格上添加一个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时,我会看到一些图像首先显示为上图所示的图像,然后在加载完成后更改为正确的图像,我只是不知道是什么导致问题。

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

【问题讨论】:

  • 你的链接不好

标签: ios uiview uiimage uicollectionview uicollectionviewcell


【解决方案1】:

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

  • 第一种方法(好方法):您将 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

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

【讨论】:

  • 非常感谢!您提供的第一个解决方案确实有效,并且可以解决所有问题。谢谢! :)
  • 发现这非常有用。特别是 prepareForReuse() 方法和所需的清理。当我发现我的单元格多次出现时,或者出现多个 titleLabels 时,我已将其放置在单元格内以测试 collectionview 的顺序。
  • 终于!!我遇到了显示旧图像的问题,即使我取消设置图像 (imageView.image = nil)。这成功了:[self.imageView removeFromSuperview];数月的头痛瞬间解决!
【解决方案2】:

Swift 4 代码

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 返回 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:"你的图片名称") imageview.image = img cell.contentView.addSubview(imageview) } 返回单元格 } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 返回CGSize(宽度:50,高度:414) }

【讨论】:

  • 虽然此答案可能是正确且有用的,但如果您 include some explanation along with it 解释它如何帮助解决问题,则最好。如果有更改(可能不相关)导致它停止工作并且用户需要了解它曾经是如何工作的,这在未来变得特别有用。
猜你喜欢
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
  • 2011-08-17
  • 2015-11-09
  • 2019-01-02
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
相关资源
最近更新 更多