Getting started with UICollectionViewController Programmatically

651 views Asked by At

I am currently working on writing a UICollectionViewController to load images from a server and put the images into custom UICollectionViewCells within a UICollectionView. To make things simpler than it already is, I don't pull from a database, I just simply create an array of images that are stored locally. It works but for some reason, not all of the cells show the image until I start scrolling.

Heres an image of whats going on!

Image

I have read up on a few tutorials but they all use storyboard... I am wanting to write this programmatically.

Heres some code:

AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    JSMediaCollectionController *instagram = [[JSMediaCollectionController alloc] initWithCollectionViewLayout:[UICollectionViewFlowLayout new]];
    instagram.datasource = self;
    self.array = [NSMutableArray array];
    for (int i = 0; i < 100; i++) {
        [self.array addObject:@"instant_noodle_with_egg.jpg"];
    }

    UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:instagram];
    self.window.rootViewController = navCon;
    [self.window makeKeyAndVisible];
    return YES;
}

- (NSArray *)itemsToLoad
{
    return [NSArray arrayWithArray:self.array];
}

JSMediaController.m

- (void)viewDidLoad {
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = NO;

    // Register cell classes
    [self.collectionView registerClass:[JSMediaCollectionCell class] forCellWithReuseIdentifier:reuseIdentifier];


    self.showOneItemPerRow = false;
    // Do any additional setup after loading the view.
}

#pragma mark <UICollectionViewDataSource>
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return [[self.datasource itemsToLoad] count];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    JSMediaCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
    [cell setImage:[UIImage imageNamed:[[self.datasource itemsToLoad] objectAtIndex:indexPath.row]]];
    cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"photo-frame.png"]];
    return cell;
}

...

...

JSMediaCell.m:

@interface JSMediaCollectionCell()
@property (nonatomic) UIImageView *view;
@end

@implementation JSMediaCollectionCell

- (id)initWithFrame:(CGRect)frame
{
    if (!(self = [super initWithFrame:frame])) return nil;
    self.view = [[UIImageView alloc] initWithFrame:self.frame];
    [self.viewForBaselineLayout addSubview:self.view];
    return self;
}

- (void)setImage:(UIImage *)image
{
    self.view.image = image;
}

I greatly appreciate anyones help in getting me on the right track... Just as a reminder... As I start scrolling, the images are reloaded, but not all the cells have an image loaded in the subview... just some.

1

There are 1 answers

0
Dheeraj Gembali On

I can see that you are initialising the view property in the cell file with self.frame.

Instead, it should be self.view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];

I think you can guess what went wrong.!!!

The frame should be wrt to the cell. When the subview is added to cell, it takes the values of the origin of the cell, so it goes out of cell's view