I saw this used in a WWDC video but only very briefly. They didn't go in to how to create the actual xib file.
I've got a UITableViewCell subclass called MyCustomCell. In this I have several properties UILabels, UIImageViews, etc... all set up as IBOutlets.
Now, in my xib file...
What do I set as the file's owner? Where do I reference my MyCustomCell class is this the file's owner?
Once I've set the file's owner how do I link it with the root view of the xib?
I've tried a few settings but I keep getting errors when using it.
Oh, the code I'm using to register it is...
self.cellNib = [UINib nibWithNibName:@"MyCustomCell" bundle:nil]; [self.tableView registerNib:self.cellNib forCellReuseIdentifier:@"CustomCell"];
Thanks
There are two variants to register , but both take a parameter called forCellReuseIdentifier , which is a string that lets you register different kinds of table view cells. For example, you might have a reuse identifier "DefaultCell", another one called "Heading cell", another one "CellWithTextField", and so on.
For performance reasons, a table view's data source should generally reuse UITableViewCell objects when it assigns cells to rows in its tableView(_:cellForRowAt:) method. A table view maintains a queue or list of UITableViewCell objects that the data source has marked for reuse.
register(nib, forCellReuseIdentifier: "MyCustomCell") myTable. dataSource = self } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if let cell = tableView. dequeueReusableCell(withIdentifier: "MyCustomCell") as?
The reuse identifier is associated with a UITableViewCell object that the table-view's delegate creates with the intent to reuse it as the basis (for performance reasons) for multiple rows of a table view. It is assigned to the cell object in init(frame:reuseIdentifier:) and cannot be changed thereafter.
Normally you don't have to bother about the File's owner in that case, because when the tableView
instantiates the cell from the provided/associated UINib
along with the reuseIdentifier
. It will load all the top-level objects of the nib, and use only the first top-level object that is of class UITableViewCell
(or maybe just the first top-level-object regardless of the class? but in general you only have your UITableViewCell
in your XIB anyway — without counting the File's Owner
and the First Responder
which are only "proxies").
In fact, the tableView
will try to dequeue a cell and if it doesn't find a reusable one, it will create a new one using the UINib
you provided. It will be something similar to this:
NSArray* topLevelObjects = [self.cellNib instantiateWithOwner:nil options:0]; cell = [topLevelObjects objectAtIndex:0];
(That's of course a simplified version just to show the idea, I don't know if it actually calls these exact lines, but it should be quite close)
So the File's Owner
is not used in this particular case, and you only need to put a simple custom UITableViewCell
as the only top-level-object of your XIB file next to the existing File's Owner
anf First Responder
(that, again, are only "proxies" / "External Objects references" and won't be instantiated and won't be part of the top-level-objects returned by instantiateWithOwner:options:
).
If it still doesn't work:
reuseIdentifier
of your UITableViewCell
in IB (in the Object Inspector pane on the right once you selected your cell in IB), and used the exact same value for this reuseIdentifier
property in IB that the one you use in your code.I've found the code given in the question is fine, but you can't refer to self.tableView
in the init
method if you're using storyboards. There's some discussion about it in another question.
So the first line goes in the init
:
self.cellNib = [UINib nibWithNibName:@"MyCustomCell" bundle:nil];
But this line should go in viewDidLoad
or similar:
[self.tableView registerNib:self.cellNib forCellReuseIdentifier:@"CustomCell"];
That fixes my mysterious error, e.g. "*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle <Foo.app> (loaded)' with name 'Ogf-Sj-1ej-view-bBf-Ti-Dda''"
And, yes, I'm doing something very similar to scoop things out of Storyboards and place them in xibs for reuse across view controllers!
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