UICollectionView adding image to a cell

First of all, the way you add images in your cell is pretty dangerous. The reason is that your cells are being reused (for exemple when you scroll, or when you reloadData), and these images are never removed on reuse. So you will start seing them everywhere, and you can even get to the point where your cell contains multiple occurrences of the image. Here are two ways to do it :

  • First way (the good way) : You subclass your UICollectionViewCell, and give the subclass an “imageView” property. Then you do this in your CustomCollectionViewCell.m file :

    // 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;
    }
    

    Then in your ViewController your have to declare the new class of your collectionViewCells like this :

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

    It will ensure that the images are correctly removed on reuse, plus it’s way easier to setup the cell in your collectionView delegate.

  • Second way (The dirty way), you remove the views every time you load a new cell :

    - (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];
        }
    }
    

    This way is far easier but i wouldn’t recommend it 😛

Now try this and let me know how your bug evolves.

Leave a Comment