Missing return UITableViewCell

  • Declare the cell at the start of the method,
  • assign a value to the cell depending on section and row number,
  • throw a fatalError() in all cases that “should not occur”,
  • return the cell.

Also note that the break statements are not needed. The default
behavior in Swift is not to fall through to the next case.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell: SettingsCell

    switch(indexPath.section) {
    case 0:
        switch (indexPath.row) {
        case 0:
            cell = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath) as! SettingsCell
            cell.backgroundColor = UIColor.redColor()

        case 1:
            cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! SettingsCell
            cell.backgroundColor = UIColor.whiteColor()

        default:
            fatalError("Unexpected row \(indexPath.row) in section \(indexPath.section)")
        }
    case 1:
        switch (indexPath.row) {
        case 0:
            cell = tableView.dequeueReusableCellWithIdentifier("cell10", forIndexPath: indexPath) as! SettingsCell
            cell.backgroundColor = UIColor.redColor()

        case 1:
            cell = tableView.dequeueReusableCellWithIdentifier("cell11", forIndexPath: indexPath) as! SettingsCell
            cell.backgroundColor = UIColor.whiteColor()

        default:
            fatalError("Unexpected row \(indexPath.row) in section \(indexPath.section)")

        }
    default:
        fatalError("Unexpected section \(indexPath.section)")

    }
    return cell
}

The fatalError() error function is marked as @noreturn, so the
compiler knows that program execution will not continue from the
default cases. (This also helps to find logic errors in the program.)

The compiler verifies that a value is assigned to cell in all
other cases.

The possibility to initialize a constant (let cell ...) in this
way is new in Swift 1.2.


Alternatively, you can create a cell and return it “immediately”
in each case:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    switch(indexPath.section) {
    case 0:
        switch (indexPath.row) {
        case 0:
            let cell = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath) as! SettingsCell
            cell.backgroundColor = UIColor.redColor()
            return cell

        case 1:
            let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! SettingsCell
            cell.backgroundColor = UIColor.whiteColor()
            return cell

        default:
            fatalError("Unexpected row \(indexPath.row) in section \(indexPath.section)")
        }
    case 1:
        switch (indexPath.row) {
        case 0:
            let cell = tableView.dequeueReusableCellWithIdentifier("cell10", forIndexPath: indexPath) as! SettingsCell
            cell.backgroundColor = UIColor.redColor()
            return cell

        case 1:
            let cell = tableView.dequeueReusableCellWithIdentifier("cell11", forIndexPath: indexPath) as! SettingsCell
            cell.backgroundColor = UIColor.whiteColor()
            return cell

        default:
            fatalError("Unexpected row \(indexPath.row) in section \(indexPath.section)")

        }
    default:
        fatalError("Unexpected section \(indexPath.section)")
    }
}

Again, calling fatalError() solves the “missing return expected” compiler
error.

This pattern can be useful if there are different kinds of cells
(with different classes) created in each case.

Leave a Comment