UICollectionView doesn't contain UICollectionV

2019-01-26 03:58发布

问题:

I'm trying to add a UICollectionView to a .nib file in IB. I've worked through a few tutorials and had no problems.

In my existing app, when I drag a collection view into a view in IB and then expand the object, the CollectionView Flow Layout is there , but there is no collection view cell. I also cannot drag and drop a cell into the collection view. Also the collection view is displayed differently, showing an image of a grid of cells instead of the normal white box.

I've tried creating a new view controller with nib, and have the same results when adding a collectionView.

This app WAS targeting iOS 4.2, but I've changed the deployment target to iOS 6.

In any newly created projects I don't get this behavior.

回答1:

I can't tell you why it does not work, but for me the subclass approach from this blog post solved the problem:

http://www.adoptioncurve.net/archives/2012/09/a-simple-uicollectionview-tutorial.php

here is a short summary:

  • create a new class MyViewCell which extends UICollectionViewCell and create properties, actions, outlets and methods as needed.

@interface MyViewCell : UICollectionViewCell

  • create a View (xib file) with a Collection View Cell as its root object (and delete the object which is created by default).
  • in the attributes set the custom class of this Collection View Cell to your extended class MyViewCell (instead of the default UICollectionViewCell).
  • in the attributes under Collection Reusable View define an Identifier, e.g. myCell, you will need this later to register your call.
  • go back to your custom class and modify the inithWithFrame method to load and use your created view.

    - (id)initWithFrame:(CGRect)frame 
    { 
       self = [super initWithFrame:frame]; 
       if (self) 
       { 
         // Initialization code 
         NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"CVCell" owner:self options:nil];
    
         if ([arrayOfViews count] < 1) { return nil; }
    
         if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) { return nil; }
    
         self = [arrayOfViews objectAtIndex:0];
       }
       return self;
    }
    
  • then you can register this class to be used by the collectionView with

[self.collectionView registerClass:[MyViewCell class] forCellWithReuseIdentifier:@"myCell"];



回答2:

It's been a while since the question has been asked but I faced the same issue lately.

Eventually, I found the answer here.

In short:

  • You cannot drag and drop a UICollectionViewCell into a UICollectionView if you are in a .xib file. This is only possible in a storyboard.
  • The workaround is to create a .xib file for your custom cell and to register the cell manually using:

    [self.collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:CELL_ID];



回答3:

Define your cell view in a separate nib file. The view must be of type UICollectionViewCell or a subclass.

Then, you must register the nib with your collection view:

- (void)viewDidLoad
{
    UINib *cellNib = [UINib nibWithNibName:@"MyNib" bundle:nil];
    [self.collectionView registerNib:cellNib forCellWithReuseIdentifier:@"cell"];
}


回答4:

While these answers are correct, the underlying cause of the problem is quite subtle and Apple needs to update their error message in the log. When you see:

Unknown class MyViewCell in Interface Builder file.

What it actually means is that your source code is missing the @implementation declaration or that the .m file has not been added to the target. So check your code and make sure you have:

@implementation MyViewCell

@end

This is true for both UITableViewCell and UICollectionViewCell.

I discuss the problem further at https://stackoverflow.com/a/12755891/539149 for the general case.

The interesting thing is that if you are missing the @implementation and call:

[self.myCollectionView registerClass:[MyViewCell class] forCellWithReuseIdentifier:@"MyViewCell"];

You will see:

Undefined symbols for architecture armv7:
  "_OBJC_CLASS_$_MyViewCell", referenced from:
      objc-class-ref in MyViewController.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

So Apple knows about the problem, they just aren't detecting it during compilation. I would advise against putting custom cells in separate nibs or calling registerClass: forCellWithReuseIdentifier:. It's much cleaner to store the custom cell inside of its container UICollectionView or UITableView in Interface Builder.