Swift tableView.dequeueReusableCell Never Returning Nil
You don't need to check if the cell is nil using this dequeue method, as long as you've register a cell class for reuse, or provided a prototype in Interface Builder.
let cell = tableView.dequeueReusableCellWithIdentifier("CellSubtitle", forIndexPath: indexPath) as! UITableViewCell
If however, you want to continue manually initializing the cells, you can use the following dequeue method instead. (keep in mind, this is the old way)
let cell = tableView.dequeueReusableCellWithIdentifier("CellSubtitle") as? UITableViewCell
Then as far as initializing the detailTextLabel goes, you don't have to. It's built into the cell, and by specifying that the cell's style should be subtitle, that label will be set up for you.
Note that the casts aren't necessary in Swift 2.
Getting nil from dequeueReusableCellWithIdentifier
Yes, you are instantiating the view controller wrong. By creating it like you are, it's totally programmatic and thus bypasses the storyboard entirely
Make sure you need to give the view controller scene an identifier in the Storyboard.
Assumptions:
- Storyboard filename: "Main.storyboard"
- View Controller scene identifier: "RegisterTableViewController"
Objective-C
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
RegisterTableViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"RegisterTableViewController"];
[self presentViewController:viewController animated:YES completion:nil];
Swift
let storyboard = UIStoryboard.init(name: "Main",bundle:nil)
let viewController = storyboard.instantiateViewControllerWithIdentifier("RegisterTableViewController")
self.presentViewController(viewController, animated: true, completion: nil)
dequeueReusableCellWithIdentifier returns nil
As maddy stated in the comments, you should create the cell yourself if it is nil, alternatively in your viewDidLoad
or where appropriate, you can call one of these methods to make the tableview create the cells for you
Objective-c
[self.tableView registerClass:<#(__unsafe_unretained Class)#> forCellReuseIdentifier:<#(NSString *)#>]
[self.tableView registerNib:<#(UINib *)#> forCellReuseIdentifier:<#(NSString *)#>]
Swift
tableView.register(MyTableViewCell.self, forCellReuseIdentifier: "CellID1")
tableView.register(UINib(nibName: "yourNibName", bundle: nil), forCellReuseIdentifier: "CellID2")
When will dequeueReusableCell return nil?
That code isn't correct. The older form of dequeueReusableCell
without the indexPath
parameter returns nil
when there isn't an available cell in the reuse pool (i.e. when the table view first appears). In that case it is your responsibility to allocate a cell.
The newer form of dequeueResuableCell
, shown in your question, will always return a cell as it allocates a cell if required.
The expression in your question can return nil
if the conditional downcast fails (that is, the cell that was returned wasn't an instance of CustomCell
).
I would argue that this represents a serious misconfiguration somewhere and should be found during development. For this reason a forced downcast is normally used; during development you get a crash, fix the problem and move on.
let cell = tableView.dequeueReusableCell(withIdentifier: customCellIdentifier, for: indexPath) as! CustomCell
The code in your question is some sort of Frankenstein mixture of the old and the new.
dequeueReusableCellWithIdentifier always returns nil (not using storyboard)
I was making a couple of mistakes:
- I was using a subclass of
UITableViewController
, but was creating the tableView outside of the subclass - There is a
tableView
created in the table view controller, which isself.tableView
In the tableview controller while returning the cell for index path, I was usingself.tableView
instead oftableView
. Also, ensure that the cell identifier is declared as
static
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Since tableView
and self.tableView
were representing different tables, the cell was not being dequeued from the same table and hence was always nil
dequeueReusableCellWithIdentifier keeps returning nil
To dequeue a cell from a storyboard, you need to use the method which takes an index path. That is, don't use:
dequeueReusableCellWithIdentifier(_:)
Instead, use:
dequeueReusableCellWithIdentifier(_:forIndexPath:)
The hacky approach in the question you linked to no longer works. This method returns a header. Don't dequeue a cell.
You should use registerNib(_:forHeaderFooterViewReuseIdentifier:)
or registerClass(_:forHeaderFooterViewReuseIdentifier:)
, and dequeueReusableHeaderFooterViewWithIdentifier(_:)
, as documented.
Related Topics
How to Convert Video (In Gallery) to Nsdata? in Swift
Date Formats from Device Based on Locale
Google Maps Sdk Not Displaying Properly in Uiview
This Code Signature Is No Longer Supported When Building App on iPhone 12
Ios: Helpfulness of Didreceivememorywarning:
How to Create a PDF File Programmatically in an iOS Application
How to Mute/Unmute Audio When Playing Video Using Mpmovieplayercontroller
How to Create Uialertcontroller in Global Swift
How to Use Afnetworking or Sthttprequest to Make a Request of a Soap Web Service
Itunes Connect: Can't See Build
Uitapgesturerecognizer on Uiimageview Within Uitablevlewcell Not Getting Called
Uipickerview as Inputview of Uitextfield
How to Remove All References for Outlet
Is Wkwebview Designed as a Replacement of Uiwebview