39

Taking first plunge with collection views and am running into this error:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindCell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

The code is very simple, as shown below. I can't for the life of me figure out what it is that I'm missing.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor]; 
return cell;
}

The collection view controller was created using a nib and the delegates & datasources are both set to file's owner.

View Controller's header file is also really basic.

@interface NewMobialViewController_3 : UICollectionViewController <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@end
Brian
  • 14,610
  • 7
  • 35
  • 43
Anti-Dentite
  • 551
  • 1
  • 6
  • 11
  • 12
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"]; – LE SANG Feb 25 '13 at 03:32
  • No, if using NIB, use [`registerNib:forCellWithReuseIdentifier:`](https://developer.apple.com/documentation/uikit/uicollectionview/1618083-registernib?language=objc). But if building cell programmatically without NIB or storyboard cell prototype, then, yes, use [`registerClass:forCellWithReuseIdentifier:`](https://developer.apple.com/documentation/uikit/uicollectionview/1618089-registerclass?language=objc). – Rob Sep 23 '19 at 22:30

15 Answers15

42

From the UICollectionView documentation for the dequeue method:

Important: You must register a class or nib file using the registerClass:forCellWithReuseIdentifier: or registerNib:forCellWithReuseIdentifier: method before calling this method.

jrturton
  • 118,105
  • 32
  • 252
  • 268
31

You need to use same identifier between the dequeueReusableCellWithReuseIdentifier's argument and the UICollectionViewCell's property.

UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionViewCell" forIndexPath:indexPath];

identifier

Kohei Mikami
  • 2,850
  • 24
  • 21
6

Complementing what @jrtuton written... What you need is:

1) Register your nib file to "connect" it with your identifier:

//MyCollectionView.m
- (void) awakeFromNib{
 [self registerNib:[UINib nibWithNibName:@"NibFileName" bundle:nil]   forCellWithReuseIdentifier: @"MyCellIdentifier"];
}

2) Use your identifier to load your custom cell from a nib:

//MyCollectionView.m
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath  *)indexPath {
    MyCustomCollectionViewCell* cell = [cv dequeueReusableCellWithReuseIdentifier:@"MyCellIdentifier" forIndexPath:indexPath];
}

3) Use always static NSString* to avoid the same identifiers again in your app.

orafaelreis
  • 2,855
  • 2
  • 28
  • 31
6

Swift 5

1) Make sure you have a correct deque for HEADER, you might be using the regular for normal cells.

override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath)
        return header
    }

2) doubleCheck the registration (ViewDidLoad)

collectionView.register(HeaderCell.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerId)
Tech Luthiers
  • 196
  • 1
  • 5
4

i had everything 100% done correctly. but for some reason i got the same error for an hour, then what i did is:

  1. go to storyboard
  2. select the prototype cell (in my case)
  3. clear the class name from identity inspector, then rewrite it
  4. rewrite the identifier name in the attributes inspector

simply, redid this step even tho i made it correct before, its like xcode misses something at a specific nanosecond!

Omar N Shamali
  • 503
  • 5
  • 11
4

Swift4.0

Whenever your UITableViewCell is xib at that time you must have to register with UITableView.

override func viewDidLoad(){
    super.viewDidLoad()

    self.yourtableview.register(UINib(nibName: "yourCellXIBname", bundle: Bundle.main), forCellReuseIdentifier: "YourCellReUseIdentifier")
   }
Rakesh Patel
  • 1,673
  • 10
  • 27
2

Please be sure to check the ViewController Custom Class correct if the project is having multiple ViewControllers. And then make sure whatever the "collectionView.dequeueReusableCell(withReuseIdentifier: "ABC", for: indexPath) as?" matches with the identifier used in Collection Reusable View inside the Collection View.

Raunak Priya
  • 111
  • 1
  • 3
1

If you are using storyboard instead of xib, here are few steps.

  1. Making sure you fill the right identifier of your cell.

Prototype cellAttribute panel

  1. In the ColletionViewDelegate.

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourCellName", for: indexPath)as! YourCellName
        return cell            
    }
    
  2. That's it. You also don't want to add registerClass:forCellWithReuseIdentifier: which will cause element nil error.

Allen
  • 2,979
  • 1
  • 29
  • 34
0

You need to give correct reuseble identifier in storyboard, which you have give in the code while registering the collectionViewCell.

Here is the code.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ClctnVC", for: indexPath)as! ClctnVC
    return cell            
}
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Ayush Dixit
  • 467
  • 4
  • 10
0

What fixed this for me was (roughly) same as Omar's answer, except I ended up creating a new UICollectionViewCell custom class and giving the Cell Reuse Indentifier a new / different name than the one that I had used elsewhere in the application. It worked immediately after that.

ciara staggs
  • 329
  • 2
  • 7
  • In case this is out of context - here is Omar's answer re-posted for convenience: - go to storyboard - select the prototype cell (in my case) - clear the class name from identity inspector, then rewrite it - rewrite the identifier name in the attributes inspector – ciara staggs Oct 19 '18 at 01:29
0

Just in case, if you are working with storyboard set collectionView identifier in the right place in the Attributes Inspector -> Identifier field. Not under the class name in "Restoration ID".

If you are using collection view in tableView cell, add delegates to tableView cell not in the tableViewController.

Egzon P.
  • 4,498
  • 3
  • 32
  • 31
0

I had the same problem.
When I created a CollectionViewController, the default reuseIdentifier was Cell with capital C, but I made a mistake and made my cell identifier in Storyboard to be cell
They must be the same.

stackich
  • 3,607
  • 3
  • 17
  • 41
0

If you ever try solution in answer another in issue not work but in code is correct syntax ,correct outlet UI.

You should check in you tableview or collectionview then check you maybe forget set delegate "tableview.delegate = self or collectionview.delegate = self"

collectionview.delegate = self
collectionview.dataSource = self

In my case is only you design collection overlap collection in your cell.

enter image description here

thank you.

Papon Smc
  • 576
  • 4
  • 11
-1

I know this is an old one, but I've experienced the same problem and wanted to share what fixed it for me.

In my case, I've declared a global identifier

let identifier = "CollectionViewCell"

and had to use self right before using it:

collectionView.dequeueReusableCellWithReuseIdentifier(self.identifier, forIndexPath: indexPath) as! CollectionViewCell

Hope this helps someone :)

Jacob.B
  • 771
  • 1
  • 9
  • 19
-1

If you create it by code, you must create a custom UICollectionViewCell, Then, init a UICollectionView ,and use loadView to set the view is the UICollectionView that you create. If you create in viewDidload() , it does not work. In addition, you can also drag a UICollectionViewController, it saves a lot of time.

lmiguelvargasf
  • 63,191
  • 45
  • 217
  • 228
N.nnd
  • 15
  • 8