11

I have never used UICollectionViewControllers, and I thought that they were somewhat similar to UITableViewControllers, but to my surprise, I cannot add UI elements to my custom UICollectionViewCells in the same way as I do with custom UITableViewCells.

In fact, I can add labels, buttons, etc. in the Interface Builder, but when I run the application, the cells appear empty.

I have registered the cell class during the viewDidLoad method by calling (void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier, and I've checked that I am returning a valid instance of UICollectionViewCellin the (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath method.

What am I doing wrong?

neutrino
  • 2,267
  • 3
  • 18
  • 28
  • Possible duplicate of http://stackoverflow.com/questions/18201574/uicollectionview-dont-show-the-cell/18201639#18201639. See my answer there. It's not quite the same problem, but my answer will fix your problem. – rdelmar Jan 14 '15 at 16:21
  • @rdelmar Thank you very much! That solves the problem! – neutrino Jan 14 '15 at 16:32

3 Answers3

30

My full explanation is here.

Create a custom class for the UICollectionViewCell:

import UIKit
class MyCollectionViewCell: UICollectionViewCell {

    // have outlets for any views in your storyboard cell
    @IBOutlet weak var myLabel: UILabel!
}

In the storyboard make the cell use this class

enter image description here

And set the Identifier for the cell

enter image description here

Don't use the registerClass...forCellWithReuseIdentifier in viewDidLoad. But you will refer to it in collectionView...cellForItemAtIndexPath:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    // get a reference to our storyboard cell
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! MyCollectionViewCell

    // Use the outlet in our custom class to get a reference to the UILabel in the cell
    cell.myLabel.text = self.items[indexPath.item]
    cell.backgroundColor = UIColor.yellowColor()

    return cell
}

Hook up the outlets from the Views in your storyboard cell to the MyCollectionViewCell class.

Community
  • 1
  • 1
Suragch
  • 364,799
  • 232
  • 1,155
  • 1,198
  • How do i connect labels in custom class to story board? – Zeeshan Shabbir Mar 18 '17 at 05:47
  • @ZeeshanShabbir, Control drag from the label in the storyboard to the `@IBOutlet` label in the code. – Suragch Mar 18 '17 at 09:58
  • When I do this, I can see what I put in my custom cell, but the selection of the cell isn't triggering at all. If I use the `registerClass` setup, then I can detect when you tap a cell, but the label I put in my storyboard isn't connected. (which makes sense, because I'm not registering the storyboard version). How can I get selection to work with the setup shown in this example? (Note: I have two collectionViews in my ViewController - the other one uses a xib file as it's got more complex contents. – N.W Nov 30 '20 at 03:51
  • Update - when I put my cell in a xib, I was able to get both selection and the label on the cell to work. I suspect this is a bug in xcode storyboards. I'm using Xcode 12.2. – N.W Nov 30 '20 at 04:12
4

@Suragch is spot on. I had this problem too: my UICollectionViewCell prototype's contents did not show in the cell when it got drawn.

The critical line is: "Don't use the registerClass...forCellWithReuseIdentifier in viewDidLoad". Really, don't. Not just "there is no need to", but "if you do register, it will stop your cell prototype from loading properly".

This only applies to Storyboard-based code, not .xib-based.

Ben
  • 1,123
  • 10
  • 18
0

if you want to use registerClass...forCellWithReuseIdentifier, then you should do it this way:

let nib = UINib(nibName: "TrackCollectionViewCell", bundle: nil)
collectionView.register(nib, forCellWithReuseIdentifier: "trackCellIdentifier")
sebby
  • 1
  • 1