Dequeuereusablecellwithidentifier Never Returns Nil

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.

Sample Image

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:

  1. I was using a subclass of UITableViewController, but was creating the tableView outside of the subclass
  2. There is a tableView created in the table view controller, which is self.tableView In the tableview controller while returning the cell for index path, I was using self.tableView instead of tableView.
  3. 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



Leave a reply



Submit