0

I'm working on a project similar to a video album. In that I'm using UICollectionView to display the thumb images of those videos. The worst part is that I should not use storyboard or xib files. I have tried to do this programatically. I'm currently working on this code:

- (void)viewDidLoad
{
    i = 0;

    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    [layout setItemSize:CGSizeMake(self.view.frame.size.width/2.5,self.view.frame.size.width/2.5)];

    collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
    [collectionView setDataSource:self];
    [collectionView setDelegate:self];
    collectionView.backgroundColor = [UIColor whiteColor];
    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"MyCell"];

    [self.view addSubview:collectionView];

    [super viewDidLoad];
}

I have given 1 for return in numberOfSectionsInCollectionView and [myArray count] for return in numberOfItemsInSection.

-(UICollectionViewCell *) collectionView:(UICollectionView *)cV cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
   UICollectionViewCell *cell = [cV dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor blackColor];

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(cell.frame.origin.x , cell.frame.origin.y, cell.frame.size.width, (cell.frame.size.height - cell.frame.size.height/3))];

    cell.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(cell.frame.origin.x , cell.frame.origin.y, cell.frame.size.width, (cell.frame.size.height - cell.frame.size.height/3))];

    imageView.image = [UIImage imageNamed:[storeData objectAtIndex:i]];

    [cell addSubview:imageView];

    i++;

    return cell;
}

I have rechecked the images in myArray. When the view loads, the collection view shows only the first image. Other 4 cells are empty. What is wrong with my code?

Wain
  • 118,658
  • 15
  • 128
  • 151
Karthik Sivam
  • 2,505
  • 3
  • 18
  • 24

4 Answers4

5

For those who is experiencing this problem, frame is the key. I've encountered this and changed:

cell.imageView.frame = cell.frame;

into

cell.imageView.frame = cell.bounds;

The op is using:

cell.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(cell.frame.origin.x , cell.frame.origin.y, cell.frame.size.width, (cell.frame.size.height - cell.frame.size.height/3))];

That's why this happened.

ljk321
  • 16,242
  • 7
  • 48
  • 60
1

You shouldn't be using i as a counter. The whole point of the delegate method sending you an indexPath is that it tells you what information to get from your array of source data. So, remove i and use the indexPath.row instead.

You also don't need 2 image views. But you should probably keep your special subview and not use the cells built in image view.

Wain
  • 118,658
  • 15
  • 128
  • 151
0

You do not need a counter. As indicated by Wain, use indexPath.row.

Importantly, you should not create new subviews in cellForItemAtIndexPath, but rather use this method to fill them appropriately with content. You could put the image views into your storyboard prototype cells and identify them with tags. Each cell returned from dequeueReusableCellWithReuseIdentifier will already contain the image view.

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • As I mentioned above, I should not use storyboard. – Karthik Sivam Nov 18 '13 at 10:12
  • Then check `if (cell==nil) ` and then create a cell with its subviews, otherwise do not create them again. – Mundi Nov 18 '13 at 11:52
  • Sorry to ask, will you explain me, why should I use that if condition and where should I use.? I have used before creating a cell in first line but it creates only a single cell. I was totally confused with this collection view stuff without storyboard. – Karthik Sivam Nov 18 '13 at 12:53
  • Sorry I think you need to get some more basic understanding of the SDK first. – Mundi Nov 18 '13 at 13:44
  • May be. But I know what 'if(code==nil)' means, and I know how to use it, my issue here is not with the creation of cells, its only that images are not shown. you are suggesting me to create subviews for cell in any method other than cellForItemAtIndexPath , but if you know how to do that, you can specify how. – Karthik Sivam Nov 19 '13 at 06:18
  • You only create subviews if they are not already there. Check if they exist (with subview==nil) and only create them if they don't. Use tags to identify the views (look up `viewWithTag:`). – Mundi Nov 19 '13 at 10:20
0

you should never create ui elements in cellForRowAtIndexPath:. Subclass a collection view cell like so:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        NSLog(@"INIT WITH FRAME FOR CELL");
        //we create the UIImageView here
        imageView = [[UIImageView alloc] init];
        imageView.contentMode = UIViewContentModeScaleAspectFill;
        imageView.frame = CGRectMake(cell.frame.origin.x , cell.frame.origin.y, cell.frame.size.width, (cell.frame.size.height - cell.frame.size.height/3));
        [self.contentView addSubview:imageView]; //the only place we want to do this addSubview: is here!
    }
    return self;
}

Then add that subclassed cell as a property and alter this code:]

[collectionView registerClass:[customCellClass class] forCellWithReuseIdentifier:@"MyCell"];

The perform these changes:

-(customCellClass *) collectionView:(UICollectionView *)cV cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
   UICollectionViewCell *cell = (customCellClass *)[cV dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath];

    cell.backgroundColor = [UIColor blackColor];

    imageView.image = [UIImage imageNamed:[storeData objectAtIndex:indexPath.row]];

    return cell;
}

A final adjustment would be to move the the [super viewDidLoad] to this:

- (void)viewDidLoad
{
     [super viewDidLoad];
     //insert the rest of the code here rather than before  viewDidLoad
}
Michael Lorenzo
  • 628
  • 10
  • 20