By Thomas


2014-05-22 08:20:41 8 Comments

I'm working on a project which uses UICollectionView to display data which may or may not have an image.

The way I'm using is to check if the image url is not null, then add an ImageView onto the cell.

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

For those cells that have no image, the cell should look like this: https://dl.dropboxusercontent.com/u/5753236/Stackoverflow/good.png

However, some of them will still add an ImageView with cropped image on it, causing something like this: https://dl.dropboxusercontent.com/u/5753236/Stackoverflow/bad.png

I've tried using the SDWebImage, but still not solving the problem.

The other issue is that when I scroll down the UICollectionView, I would see some images displayed as the image shown above first, and then change to its correct image after loading is completed, and I just have no idea what is causing the problem.

Please help me sort out these two problems, I'd really appreciate for any help.

2 comments

@Abishek T 2018-07-02 12:12:17

Code for Swift 4

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)
}

@Tim Diekmann 2018-07-02 12:31:04

While this answer is probably correct and useful, it is preferred if you include some explanation along with it to explain how it helps to solve the problem. This becomes especially useful in the future, if there is a change (possibly unrelated) that causes it to stop working and users need to understand how it once worked.

@Kujey 2014-05-22 09:04:32

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 :P

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

@Thomas 2014-05-22 09:32:59

Thank you so much! The first solution you offered really works and that solves everything. Thank you! :)

@Kujey 2014-05-22 09:38:32

Glad I could help ;)

@Mark 2018-12-02 00:43:51

Found this very useful. In particular the prepareForReuse() method and the cleanup required. As I found there were multiple occurrances of my cell or as it appeared multiple titleLabels I'd placed inside my cell to test the order of the collectionview.

@Jaap Weijland 2019-05-01 10:04:00

Finally!! I had the problem that my old images were shown, even if I unset the image (imageView.image = nil). This did the trick: [self.imageView removeFromSuperview]; Months of headaches solved in an instant!

Related Questions

Sponsored Content

35 Answered Questions

7 Answered Questions

4 Answered Questions

15 Answered Questions

[SOLVED] UICollectionView current visible cell index

11 Answered Questions

[SOLVED] UICollectionView flowLayout not wrapping cells correctly

5 Answered Questions

6 Answered Questions

[SOLVED] UICollectionView repeats cell

0 Answered Questions

UICollectionView lags when scroll

1 Answered Questions

Sponsored Content