UICollectionView's cellForItemAtIndexPath is not being called
Only my second time using UICollectionView's and perhaps I have bitten off more than I can chew but nevertheless:
I am implementing a UICollectionView (myCollectionView) that uses custom UICollectionViewCell's that I have subclassed. The subclassed cells (FullReceiptCell) contain UITableView's and are the size of the viewcontroller. I am trying to allow for horizontal scrolling between the FullReceiptCells.
The subclassed UICollectionViewController that contains myCollectionView is being pushed on to a nav controller stack. Currently, myCollectionView loas and horizontal scrolling is enabled. However, no cells are visible. I have confirmed that
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
has run and is returning an integer greater than 0. I have also confirmed that myCollectionView's delegate and datasource are properly set in IB to the subclassed UICollectionViewController.
The method where the cells are to be loaded:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
is not being called.
Here is where I push the UICollectionViewController and my viewDidLoad method within that controller (NOTE: initWithBill is an override of the normal initializer):
In the prior ViewControllers .m file:
FullReceiptViewController *test = [[FullReceiptViewController alloc] initWithBill:currentBill];
test.title = @"Review";
[self.navigationController pushViewController:test animated:YES];
In FullReceiptViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self.myCollectionView registerClass:[FullReceiptCell class] forCellWithReuseIdentifier:@"FullReceiptCellIdentifier"];
self.myCollectionView.pagingEnabled = YES;
// Setup flowlayout
self.myCollectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];
[self.myCollectionViewFlowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
[self.myCollectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.myCollectionViewFlowLayout.minimumLineSpacing = 0;
self.myCollectionViewFlowLayout.minimumInteritemSpacing = 0;
[self.myCollectionView setCollectionViewLayout:myCollectionViewFlowLayout];
//testing to see if the collection view is loading
self.myCollectionView.backgroundColor = [UIColor colorWithWhite:0.25f alpha:1.0f];
Any clue as to why it is not being called?
Solution 1:
For those who stumble here later.... the reason:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
was not being called was because of the itemSize for the collectionViewFlowLayout's height was too big.
[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];
If I change the height to 410, it will execute cellForItemAtIndexPath.
Solution 2:
In my case, it was because my layout class incorrectly subclassed from UICollectionViewLayout
instead of UICollectionViewFlowLayout
Solution 3:
The cellForItemAtIndexPath will not get called if you do not provide the content size information to collection view.
- If you are using Flow layout: You need to set the item sizes properly.
- If you have a custom layout subclassed from UICollectionViewLayout: Ensure you are returning a proper size from the collectionViewContentSize method.
In case of the latter, you will also observe that your layoutAttributesForElementsRect is also not called. The reason is that you have not specified what is your content size and by default the size will be CGSizeZero. This basically tell collection view that you don't have any content to paint so it does not bother asking you for attributes or cells.
So, just override collectionViewContentSize and provide a proper size there, it should solve your problem.
Solution 4:
For a more complicated view hierachy please check this blog. It saved my life!
self.automaticallyAdjustsScrollViewInsets = NO;