swift multiple cell subclasses in UITableViewCOntroller

11,787

Solution 1

You are not allowed to return nil for cellForRowAtIndexPath

You could use at the end:

let cell:UITableViewCell!
return cell

instead of

 return nil

This should be (if you just have 2 sections) never get executed.

Edit:

You could also use instead of "} else if indexPath.section == 1 {" only } else { - to return a cell. I just showed up what is the problem. Or use a Switch/Case and returning an empty Cell on default.

Solution 2

You can't return nil. Instead by default return empty cell.

    var cell :UITableViewCell!

    switch (indexPath.row) {
    case 0:
        cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        cell.textLabel?.text = self.section1[indexPath.row]
        cell.accessoryType = .DisclosureIndicator
        break;

    case 1:
        cell = tableView.dequeueReusableCellWithIdentifier("SwitchViewCell", forIndexPath: indexPath) as SwitchViewCell
        (cell as SwitchViewCell).cellLabel?.text = self.section2[indexPath.row]
        break;

    default:
        break;
    }

    return cell

Make sure that you have registered the nib

 self.tableView.registerNib(UINib(nibName: "SwitchViewCell", bundle: nil), forCellReuseIdentifier: "SwitchViewCell")

Solution 3

tableView:cellForRowAtIndexPath: must return a UITableViewCell and can't return nil. So you will have to remove return nil. But it won't be enough. Your if else statement also has to be complete. What it means is that every possible section value has to be provided or, at least, send to a fallthrough.

Your if else statement should look like this:

if indexPath.section == 0 {
    /* ... */
} else if indexPath.section == 1 { 
    /* ... */
} else {
    /* ... */
}

Or like this:

if indexPath.section == 0 {
    /* ... */
} else {
    /* ... */
}

However, the following if else statement is not complete:

if indexPath.section == 0 {
    /* ... */
} else if indexPath.section == 1 { 
    /* ... */
}

In this case, tableView:cellForRowAtIndexPath: will not know what to return if any of these conditions is verified. Thus, if you try it, Xcode (that is smart) will also display an error message:

Missing return in a function expected to return 'UITableViewCell'

Therefore, the following code should work:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if indexPath.section == 0 {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell

        cell.textLabel?.text = self.section1[indexPath.row]
        cell.accessoryType = .DisclosureIndicator

        return cell
    } else {
        let cell = tableView.dequeueReusableCellWithIdentifier("SwitchViewCell", forIndexPath: indexPath) as SwitchViewCell

        cell.cellLabel?.text = self.section2[indexPath.row]

        return cell
    }
}

PS:

If you also use switch statement inside your tableView:cellForRowAtIndexPath: method in order to set your cells, this answer to a similar question may help you.

Share:
11,787
gamerChristian
Author by

gamerChristian

Updated on June 12, 2022

Comments

  • gamerChristian
    gamerChristian almost 2 years

    i'm trying to add multiple subclasses into a UITableView. The problem is that it keep giving me following error:

    Type UITableVieCell does not conform to protocol NilLiteralConvertible
    

    CellForRowAtIndexPath

    override  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        if indexPath.section == 0 {
    
            let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    
            cell.textLabel?.text = self.section1[indexPath.row]
            cell.accessoryType = .DisclosureIndicator
    
            return cell
    
        } else if indexPath.section == 1 {
    
            let cell = tableView.dequeueReusableCellWithIdentifier("SwitchViewCell", forIndexPath: indexPath) as SwitchViewCell
    
            cell.cellLabel?.text = self.section2[indexPath.row]
    
            return cell
        }
    
        return nil
    }