IkegawaTaro
IkegawaTaro

Reputation: 3563

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?

Upvotes: 126

Views: 108392

Answers (30)

Manish Mahajan
Manish Mahajan

Reputation: 2082

Below is my observation:

if sizeForItemAt method of UICollectionViewDelegateFlowLayout returns 0 size then cellForItemAt will not call.

So collection view will not show up.

Upvotes: 1

Alex
Alex

Reputation: 7612

reloadSections instead of reloadData did it for me.

I don't know why reloadData did not work.

Upvotes: 1

Gangadhar
Gangadhar

Reputation: 86

i) Please make sure to add the UICollectionView to UITableViewCells contentView and not as subView

Upvotes: 0

Hardik Darji
Hardik Darji

Reputation: 3684

In my case, I found workaround by this:

  //IF RELOAD COLLECTION VIEW AFTER DELAY IT WORKS
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
        //ASSIGN NEW DATA SOURCE
        self.arrItem = arrModel
        self.collectionView.reloadData()
    }

Upvotes: -1

NFC.cool
NFC.cool

Reputation: 3303

In my case I had the collectionView in a UIStackView with alignment = .center. So the collectionView did not have a width. When setting the stackView.alignment to .fill everything was fine.

Upvotes: 6

Wouter
Wouter

Reputation: 790

I was having a similar problem. But instead cellForItemAtIndexPath was called when the number of items was > 1, but not when there was only a single item. I tried many of the proposed solutions here and similar to many I found that it had to do with item sizing. For me the solution was to change the estimate size of the UICollectionView from Automatic to Custom.

Set estimate size to Custom

Upvotes: 7

tobi
tobi

Reputation: 1

In my case I had to adjust the estimated Content size. content size did not do it.

  let layout = collectionVC.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
    layout.itemSize = CGSize(width: 100, height: 100)
    layout.estimatedItemSize = CGSize(width: 100, height: 100)

Upvotes: 0

Declan McKenna
Declan McKenna

Reputation: 4870

If you're using collection view protocols you must connect the CollectionViewDataSource and CollectionViewDelegate protocols to your ViewController. Interface builder outlets

Upvotes: 3

poGUIst
poGUIst

Reputation: 334

In storyboard/xib UICollectionView property cellSize MUST not be {0, 0}

Upvotes: 3

Gurjinder Singh
Gurjinder Singh

Reputation: 10299

If your class is subclass from UICollectionviewController and you are creating collectionView programmatically then use

let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .Vertical
    layout.itemSize = CGSizeMake(50, 50)

    collectionView?.setCollectionViewLayout(layout, animated: false)

Upvotes: 15

Khaled Annajar
Khaled Annajar

Reputation: 16552

In my case the collection view was not fully visible in its parent view due to wrong auto layout constraints. So fixing the constraints made the collection view all visible and cellForItemAtIndexPath was called.

Upvotes: 2

AamirR
AamirR

Reputation: 12198

I was using autolayout, and in my case height constraint was missing

Upvotes: 12

erdikanik
erdikanik

Reputation: 744

It can be realated layout problems. Check layout warnings from console, if exist.

Upvotes: 2

inokey
inokey

Reputation: 6170

When using UICollectionViewDelegateFlowLayout be careful on what this function returns. Both width and height should be greater than 0. I used window as frame reference but due to complicated view hierarchy window was nil at runtime. If you need adjust the width of the element based on screen width use UIScreen.main.bounds.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: 
           UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {}

Upvotes: 2

nebyark
nebyark

Reputation: 131

My issue was that I had 2 collection views within the same view, and both were sharing a computed UICollectionViewFlowLayout instance. Once I created separate instances of the same flow layout, it worked fine.

Upvotes: 6

Tim
Tim

Reputation: 955

Just resolved this issue, for a somewhat specific situation.

In my case, I was manually initializing the UICollectionViewController in a parent ViewController, and then adding the UICollectionViewController's view as a subview.

I resolved the issue by calling 'setNeedsLayout' and/or 'setNeedsDisplay' on the collectionView in the parent's viewDidAppear:

- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   [_collection.view setNeedsLayout];
   [_collection.view setNeedsDisplay];
}

Upvotes: 1

Míng
Míng

Reputation: 2608

For me, I update the height of self.view (the collectionView's superview) via autolayout, and MUST call layoutIfNeeded after that.

[self.view mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.equalTo(@(height));
}];
[self.view layoutIfNeeded];

Upvotes: 2

6david9
6david9

Reputation: 804

In my case, set collectionView.prefetchingEnabled = NO; solved my problem. Only works on iOS 10.

Upvotes: 5

sasha_nec
sasha_nec

Reputation: 542

Also, make sure that reloadData is not called while collection view is updating with animation (insert, delete, update or performBatchUpdates).

Upvotes: 5

Stritt
Stritt

Reputation: 547

I forgot to set the autoresizing mask to false on the collection view:

collectionView.translatesAutoresizingMaskIntoConstraints = false

Upvotes: 5

esilver
esilver

Reputation: 28463

In my case, it was because my layout class incorrectly subclassed from UICollectionViewLayout instead of UICollectionViewFlowLayout

Upvotes: 121

wfbarksdale
wfbarksdale

Reputation: 7606

I sunk a bit of time with this issue coming op with a CollectionView in a Contained view controller loaded from a storyboard. I ended up just deleting the contained view controller, and recreating it in the storyboard, and this seemed to get rid of the issue. My guess is there was some kind of storyboard corruption that had taken place.

Upvotes: -1

Jaybo
Jaybo

Reputation: 954

For a more complicated view hierachy please check this blog. It saved my life!

self.automaticallyAdjustsScrollViewInsets = NO;

Upvotes: 18

Javal Nanda
Javal Nanda

Reputation: 1838

Setting collectionView frame inside custom cell's layoutSubViews() worked for me:

override func layoutSubviews() {
        super.layoutSubviews()
        let frame = self.contentView.bounds
        self.CollectionView.frame = frame
    }

Upvotes: -2

Bart van Kuik
Bart van Kuik

Reputation: 4862

In Xcode 7.0.1, we got this problem when we copied a storyboard and accompanying code from another project. The collection view had a custom flow layout set in the storyboard. Solution was to:

  • Remove the flow layout in IB
  • Compile/run the app
  • Set the flow layout back

Now it worked :)

Upvotes: 3

chanil
chanil

Reputation: 361

In my case, changing UINavigationBar's translucent to NO solved the problem.

Upvotes: 3

Vincent Sit
Vincent Sit

Reputation: 2352

Ten minutes ago I also encountered this problem, I made a silly mistake.

My intention is to use UICollectionViewFlowLayout,

But because of mistakes, I used UICollectionViewLayout.

Upvotes: 4

RT Denver
RT Denver

Reputation: 74

Make sure -(NSInteger) collectionView:numberOfItemsInSection: is returning a positive (read, greater than zero) value. It may be a matter of placing [self.collectionView reloadData]; in the completion handler.

Upvotes: 2

Eran Goldin
Eran Goldin

Reputation: 969

Make sure numberOfSectionsInCollectionView returns a positive integer as well.

There has to be at least one section in the collection.

Upvotes: 2

Hafeez
Hafeez

Reputation: 403

Same happened to me. I had 2 UICollectionViews and I removed once since I didn't need that. After that I realised that the CellForItemAtIndexPath was not getting called but the other required methods. I tried all of the above but then I did the standard magic. Removed the collection view from storyboard and added again. Then it started working. Not sure why and I have no explanation but maybe some connection issues.

Upvotes: 1

Related Questions