jefflovejapan
jefflovejapan

Reputation: 2121

UICollectionViewCell subclass containing UIImageView outlet not displaying image

I have a UICollectionViewCell subclass called AlbumCVC that contains a single IBOutlet --- a UIImageView called cellView. I'm setting the value of cellView for each cell inside the following method:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    UICollectionViewCell *cell;

    cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"albumPhotoCell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor blueColor];
    if ([cell isKindOfClass:[AlbumCVC class]]){
        AlbumCVC *albumCVC = (AlbumCVC *)cell;
        ALAsset *thisImage = [self.albumPhotos objectAtIndex:indexPath.item];        

        albumCVC.imageView.frame = albumCVC.contentView.frame;
        albumCVC.contentView.contentMode = UIViewContentModeScaleAspectFit;
        albumCVC.imageView.image = [UIImage imageWithCGImage:[thisImage aspectRatioThumbnail]];

        }
    }
    return cell;
}

where albumPhotos is an NSMutableArray of ALAssets. I'm sure that the property is getting set correctly because I get sensible results when I log the albumCVC.cellImage.image.bounds.size. Cells are also sized properly as the frames are visible when I set the background color. But for some reason, cellImage won't display. Is there another method call I need to make inside collectionView:cellForItemAtIndexPath: in order to get the image to show up?

Update: On the advice of a very smart friend, I tried moving the UIImageView out of the cell, putting it elsewhere in the main view, and everything worked lovely. The problem appears to have something to do with the frame / bounds of the UIImageView. I think there's a method call I need to make so that the cell's subview expands to fit the newly-resized cell following the call to collectionView:layout:sizeForItemAtIndexPath:. The problem now is that UIImageView.image.size is a read-only property, so I can't resize it directly.

Update 2: On another piece of advice I looked at the frame and bounds of the cell's contentView and cellImage and found that they weren't matching up. Added another method call to make them equal, and even changed contentMode to UIViewContentModeScaleAspectFit in order to try and get the cell to render the thumbnail properly. Unfortunately, I'm still getting tiny thumbnails inside huge cells. Any idea why? Updated code above and below.

For the sake of completeness, here's the entire class implementation:

#import "AlbumViewController.h"
#import "AlbumCVC.h"
#import <AssetsLibrary/AssetsLibrary.h>

@interface AlbumViewController ()
@end

@implementation AlbumViewController


#pragma constants

const int IPHONE_WIDTH = 320;

#pragma delegate methods

- (NSInteger)collectionView:(UICollectionView *)collectionView
     numberOfItemsInSection:(NSInteger)section{

    // Get the count of photos in album at index albumIndex in the PhotoHandler
    NSInteger numCells = [self.group numberOfAssets];
    return numCells;

}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    UICollectionViewCell *cell;

    cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"albumPhotoCell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor blueColor];
    if ([cell isKindOfClass:[AlbumCVC class]]){
        AlbumCVC *albumCVC = (AlbumCVC *)cell;
        ALAsset *thisImage = [self.albumPhotos objectAtIndex:indexPath.item];
        }

        albumCVC.imageView.frame = albumCVC.contentView.frame;
        albumCVC.contentView.contentMode = UIViewContentModeScaleAspectFit;
        albumCVC.imageView.image = [UIImage imageWithCGImage:[thisImage aspectRatioThumbnail]];

    }
    return cell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout*)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath{


    //Copy a pointer to an asset from the album
    ALAsset *thisImage = [self.albumPhotos objectAtIndex:indexPath.item]; //Zen - are you sure thisImage represents a valid image?

    //Copy that asset's size and create a new size struct
    CGSize thisSize = thisImage.defaultRepresentation.dimensions;
    CGSize returnSize;

    // force all previews to be full width
    returnSize.width = IPHONE_WIDTH;
    returnSize.height = IPHONE_WIDTH * thisSize.height / thisSize.width;

    return returnSize;
}


#pragma lifecycle methods

- (void)viewWillAppear:(BOOL)animated{
    [self.albumPhotos removeAllObjects];

//"handler" is a class that manages calls to the ALAssetLibrary. self.albumIndex is an integer that gets set on segue. As far as I can tell, everything in the below method is working fine --- cells are sized properly.

    self.group = self.albumDelegate.handler.groups[self.albumIndex];
    [self.group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
        if (result) {
            NSLog(@"Just added an object to albumPhotos.");
            [self.albumPhotos addObject:result];
            NSLog(@"The item in albumPhotos is class %@", [self.albumPhotos[0] class]);
        }
    }]; 

}


#pragma instantiation

- (ALAssetsGroup *)group{
    if (!_group) {
        _group = [[ALAssetsGroup alloc]init];
    }
    return _group;
}

- (NSMutableArray *)albumPhotos{
    if (!_albumPhotos) {
        _albumPhotos = [[NSMutableArray alloc]init];
    }
    return _albumPhotos;
}

@end

Update 3: I can't be certain what the problem was initially, but I know that it now works with the following cellForItem implementation:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    UICollectionViewCell *cell;
    cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"albumPhotoCell" forIndexPath:indexPath];
    if ([cell isKindOfClass:[AlbumCVC class]]) {
        AlbumCVC *albumCVC = (AlbumCVC *)cell;
        albumCVC.albumImageView.image = [[UIImage alloc] initWithCGImage:[self.albumAssets[[self reverseAlbumIndexForIndex:indexPath.item]] thumbnail]];
    }
    cell.alpha = [self alphaForSelected:self.selectedItems[@(indexPath.item)]];
    return cell;
}

There's no screwing around with frames or bounds anywhere, everything just works. Maybe it's the difference between [[UIImage alloc]initWithCGImage] and [UIImage imageWithCGImage]?

Upvotes: 0

Views: 2116

Answers (1)

rpledge
rpledge

Reputation: 61

I've had a similar issue and resolved it by setting the UICollectionViewCell frame property to be the same as the UIImageView's frame. I'm not 100% sure that this is your issue, I was building the collection purely in code (no Storyboard)

Upvotes: 1

Related Questions