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.
Sample project
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.