Error could not dequeue a view of kind UICollectio

2020-02-10 00:19发布

问题:

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

回答1:

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.



回答2:

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

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



回答3:

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.



回答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!



回答5:

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

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

  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.



回答6:

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")
   }


回答7:

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)


回答8:

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 :)



回答9:

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            
}


回答10:

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.



回答11:

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.



回答12:

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.