Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dequeue subtitle UITableViewCell in code properly?

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?

like image 669
SpacyRicochet Avatar asked May 23 '26 01:05

SpacyRicochet


1 Answers

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
    }

}

enter image description here

like image 194
Mat Avatar answered May 25 '26 07:05

Mat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!