Creating a custom UICollectionViewCell
for my UICollectionViewController
, it works by registering the nib; however, fails to register by class.
Using registerClass() - fails
Registering by class seems correct - it builds, but throws an exception at runtime unwrapping optional elements from the UIView. Without referencing outlets, it runs; however, no cells appear within the collection view.
collectionView?.registerClass(MyCollectionViewCell.self,
forCellWithReuseIdentifier: "myCell")
Clearly the view is not loaded; however, I'd think setting the custom class of the cell would provide necessary linkage.
Using registerNib() - works
Registering by nib works, which makes sense as it is explicitly loading the view.
let nib = UINib(nibName: "MyCollectionViewCell", bundle: nil)
collectionView?.registerNib(nib, forCellWithReuseIdentifier: "myCell")
Here the view is explicitly referenced, and custom class is set for the view; however, something about this seems wrong.
Isolating the issue in a sample project, below are views and code to replicate; or, this project is available at GitHub.
Main.storyboard
My main storyboard initial view controller is a UICollectionViewController
subclassed as MyCollectionViewController
:
MyCollectionViewController.swift
Showing both registering by nib, and by class:
import UIKit
class MyCollectionViewController: UICollectionViewController {
var data = [String]()
override func viewDidLoad() {
super.viewDidLoad()
data = ["a", "b", "c"]
// This works, by nib
let nib = UINib(nibName: "MyCollectionViewCell", bundle: nil)
collectionView?.registerNib(nib, forCellWithReuseIdentifier: "myCell")
// This fails, by class
//collectionView?.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: "myCell")
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath) as! MyCollectionViewCell
cell.title.text = data[indexPath.row]
return cell
}
}
MyCollectionViewCell.xib
View is a UICollectionViewCell
subclassed as MyCollectionViewCell
with a UILabel
:
In my nib the Collection Reusable View Identifier has been set to: myCell
:
MyCollectionViewCell.swift
Defines the class, and has an IBOutlet
to the label:
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var title: UILabel!
}
Using the nib, execution appears as:
Why can't I register UICollectionViewCell
by class?
As well, I'm a little fuzzy as to whether the prototype cell needs to remain on the main storyboard collection view controller. There, I have not defined any reusable view identifier.
I see this link Overview Collection View
If the cell class was written in code, the registration is performed using the registerClass: method of UICollectionView. For example: [self.myCollectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"MYCELL"]; In the event that the cell is contained within an Interface Builder NIB file, the registerNib: method is used instead.
So your collection cell create with nib, you should register with nib. If your cell written totally in code you will need register with class.
Hope this help.
Actually if you register the class in the storyboard and give it a reuse identifier there, then you shouldn't be registering it's class or it's nib in code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With