63

This could be a duplicate post but I haven't found the solution.

I'm setting my UICollectionView as:

UINib *nib = [UINib nibWithNibName:@"CollectionViewCell"
                           bundle:[NSBundle mainBundle]];
[_collectionView registerNib: nib forCellWithReuseIdentifier:@"bCell"];

(I've tried to set a delegate, without delegate, etcetera).

But then, only the

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section gets called while

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath doesn't.

I've checked the numberOfItemsInSection I return, and it's always > 0 (it's exactly 17).

I've checked to call [_collectionView reloadData]; and nothing happens either.

I've tried different things but I can't make it work.

Furthermore, my UICollectionView should be here but it's not:

enter image description here

Does anyone have a clue? Thank you.

Matteo Gobbi
  • 16,670
  • 3
  • 24
  • 38
Rafael Ruiz Muñoz
  • 4,769
  • 6
  • 41
  • 79
  • have you added "numberofsectionsincollectionview" method..? Please put delegate and datasource methods by this we can help you more. – V.J. Jun 12 '15 at 14:15
  • 2
    `collectionView:cellForItemAtIndexPath:` will be called only if item exists (i.e. item present for indexPath) and are visible. For instance, what's the size of the cells? Did you put some "space" between them, etc. DO you call `reloadData` in main thread? – Larme Jun 12 '15 at 14:22

18 Answers18

59

Ok I think this could be useful for future problems with this...

It was because of constraints on the StoryBoard. I don't really understand why that happens, because I just had fixed an horizontal space. I removed the horizontal space as constraint for that View and everything works fine.

Well, let's life flow.

Rafael Ruiz Muñoz
  • 4,769
  • 6
  • 41
  • 79
  • 8
    I was missing a height constraint. Thanks for the hint. Saved me some time for sure. :) – Robert Gummesson Apr 04 '16 at 21:17
  • Ok, I know I need to find a constraint that causes this issue but I can't figure out which constraint to change. Can somebody explain how to look for? – Murat Yasar Jul 30 '16 at 11:13
  • 1
    look for the specific constraints of collectionView. In my case, the top constraint was trying to set distance with an removed element.. – Eva Madrazo Oct 05 '16 at 09:53
  • 2
    It's bizarre that this still works. :) I literally was pulling my hairs of trying to figure out what the issue was and then after I saw this, just created a height constraint and it started working. – AnBisw Jul 10 '17 at 22:29
  • 1
    Thanks you so much! I think it's kinda stupid for apple to have this issue. Maybe I don't want constraints!! – Arnaldo Capo Sep 16 '17 at 21:47
  • 1
    After days of debugging, THIS was the issue! Thanks Rafael! – Noam May 24 '18 at 03:40
24

I also face same issue and finally got to know that i have passed wrong class object for collectionViewLayout , i change to UICollectionViewFlowLayout instead of UICollectionViewLayout while creating object for UICollectionView like below its stared calling all delegate method.

 collectionView = UICollectionView(frame: CGRectMake(5, 0, 400, 40) , collectionViewLayout: UICollectionViewFlowLayout())
Narayana
  • 6,031
  • 22
  • 41
19

1. cellForItemAtIndexPath will be called when you return More than 0 Items on numberOfItemsInSection method.

2. Check that your UICollectionViewFlowLayout is correct or your own. UICollectionViewLayout is abstract class you can't use it directly

3. Check the size of the collection view cell & Collection view.

4. Try to set your collectionview size by in code. [yourCollectionViewFlowLayout setItemSize:CGSizeMake(200, 200)];

5.If any of them NOT works, then kill the XCode & restart . Sometimes it will fix the issue.

Apple says

The UICollectionViewLayout class is an abstract base class that you subclass and use to generate layout information for a collection view. The job of a layout object is to determine the placement of cells, supplementary views, and decoration views inside the collection view’s bounds and to report that information to the collection view when asked. The collection view then applies the provided layout information to the corresponding views so that they can be presented onscreen.

You must subclass UICollectionViewLayout in order to use it. Before you consider subclassing, though, you should look at the UICollectionViewFlowLayout class to see if it can be adapted to your layout needs.

  • 1
    I didn't explain it very well, but this is what's regarding with the number: ** I've checked the count I return, and it's always > 0 (it's exactly 17). ** – Rafael Ruiz Muñoz Jun 12 '15 at 14:07
  • `collectionViewContentSize` cannot be `.zero`, or else `cellForItemAt` will not be called. – DawnSong Aug 16 '17 at 10:49
19

I meet this problem too. I checked all the possible issues, everything looks ok. Then I tried to changed the reload methods.

[self.colView reloadData] -> [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:x]];

Then all things worked. However I still don't understand how.

Silviu St
  • 1,730
  • 3
  • 28
  • 40
frank
  • 1,978
  • 1
  • 15
  • 19
19

Add this to viewDidLoad:

self.automaticallyAdjustsScrollViewInsets = NO;
reza_khalafi
  • 5,427
  • 4
  • 44
  • 70
9

I just found that NONE of cellForItemAtIndexPath gets called (in iOS 10) as long as at least ONE cell has a height of zero.

Disclaimer: sorry if this should have been a comment - not enough reputation.

KiRviz
  • 128
  • 1
  • 4
  • 1
    It looks like `sizeForItemAtIndexPath` can't return zero if there is postitive `numberOfItemsInSection` for the same section – akaDuality May 04 '18 at 20:01
7

For me the cellForItemAtIndexPath not called for the first time after i set the constraint of the collectionView to 0 and then again setting it to its Actual Size.

 @IBOutlet weak var collectionVwHeightContraint: NSLayoutConstraint!
 if attachments.count > 0 {

     collectionVwHeightContraint.constant = 100
 }else {

     collectionVwHeightContraint.constant = 0
 }
 // collectionVwHeightContraint is my collectionView height Contraint outlet

I solved this by calling:

self.view.layoutIfNeeded()

Hope it will help someone :)

Ariven Nadar
  • 1,108
  • 11
  • 13
3

Might help somebody else, it could be 2 things:

  1. Height of the cell is not calculated properly, so need to check the constraints of the cell.

To fix this, I implemented UICollectionViewLayout's method: extension TableViewCellActionItemPageControl: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 414, height: 213) 
}
  1. Other possibility is: the size of the collection view cell returned is more that the collection view itself. Make sure the height of your cell is smaller than the height of your collective.
WingJammer
  • 71
  • 4
2

What helped me was to set the correct itemSize. My cellForItemAtIndexPath was not being called because of the wrong height.

So I set the size at:

[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(170, 300)];
Luiz Dias
  • 1,465
  • 14
  • 21
1

For me the issue was that I was creating my Collection View programmatically but I had given it CGRectZero as its frame. I was laying it out using Auto Layout after viewDidLoad. If I lay out the collection view while the view controller is loading, it ends up calling cellForItemAtIndexPath: correctly.

Liron Yahdav
  • 8,412
  • 7
  • 61
  • 90
1

For me it was that my collectionView's container didn't have translatesAutoresizingMaskIntoConstraints = false

Jeremy Kelleher
  • 277
  • 3
  • 13
1

In my case, it was working alternatively. then I run reloadData() on the main thread and the issue fixed. But later after certain changes again the same issue arose. Finally, I made it like below. Now no issues, I feel self.view.layoutIfNeeded() plays a key role

DispatchQueue.main.async {
                self.view.layoutIfNeeded()
                self.collectionView.reloadData()
            }
0

I had same problem with collection view outlet on a storyboard with "standard" constraints (bottom, top, leading, trailing fixed to inner view).

I solved in this way:

let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.itemSize = self.collectionView.frame.size
Luca Davanzo
  • 18,777
  • 12
  • 102
  • 136
0

I had faced a similar problem. The issue was with the numberOfItems in section. Your cellForRowAtIndexPath might not be called if either your number of sections or number of rows in section is below zero.

iPhoneDeveloper
  • 768
  • 1
  • 10
  • 22
0

In my case, I messed up with my custom cell label constraints. Verify your constraints once again.

Madhurya Gandi
  • 837
  • 8
  • 12
0

reza_khalafi answer worked for me, i am using Xcode 11 and swift 4.2. swift 4.2 version of reza's answer.

add this on viewDidLoad

self.automaticallyAdjustsScrollViewInsets = false
Faris Muhammed
  • 577
  • 7
  • 13
0

In my case, collectionViewCell's height was greater than CollectionView height.

Niki
  • 1,315
  • 1
  • 8
  • 25
0

To complete @frank answer: (swifty answer)

extension UICollectionView {
   func reloadFirstSection() {
        let indexPath = IndexPath(item: 0, section: 0)
        reloadSections(IndexSet(integer: indexPath.section) )
    }
}

and then instead of collectionView.reloadData() call collectionView.reloadFirstSection()

Mehrdad
  • 613
  • 1
  • 9
  • 18