I'm trying to create a UITableView with regular, non-custom .subtitle cells in pure code. However, the following code never gives me a cell with a proper detailTextLabel, instead opting for a .default cell.
public var cellIdentifier: String { return "wordsCell" }
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell
if let newCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) {
// Always succeeds, so it never goes to the alternative.
cell = newCell
}
else {
// This is never reached.
cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)
}
let word = wordAtIndexPath(indexPath: indexPath)
cell.textLabel?.text = word.text
cell.detailTextLabel?.text = word.subText
return cell
}
This is apparantly because dequeueReusableCell(withIdentifier:) doesn't actually return nil, even if no cell is currently available. Instead, it always returns a .default if no cells have been created.
The other option, dequeueReusableCell(withIdentifier:for:) also always succeeds, so that wouldn't work either.
So far, it looks impossible to create a non-.default style cell in pure code, without Interface Builder to define the style of a prototype cell. The closest I can come up with is this answer, which notices the same problem. All the other questions I found also address either IB issues or custom cells.
Does anyone know how to dequeue a .subtitle cell for a table view without using Interface Builder?
I tested it and it works. I thought you wanted to subclass UItableViewCell but you don't have to register the cell in this case.
class TableViewController: UITableViewController {
let wordAtIndexPath = ["one", "two", "three"]
let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return wordAtIndexPath.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let word = wordAtIndexPath[indexPath.row]
let cell: UITableViewCell = {
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellId) else {
return UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: cellId)
}
return cell
}()
cell.textLabel?.text = "My cell number"
cell.detailTextLabel?.text = word
return cell
}
}

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