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!
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.
I can see that you are initialising the
view
property in the cell file withself.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