gamerChristian
gamerChristian

Reputation: 481

swift multiple cell subclasses in UITableViewCOntroller

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
}

Upvotes: 7

Views: 11889

Answers (4)

Eray Alparslan
Eray Alparslan

Reputation: 814

In my situation, I did the following:

let cellOne = mTableView.dequeueReusableCell(withIdentifier: "CellOne") as! customTableViewCellOne
let cellTwo = mTableView.dequeueReusableCell(withIdentifier: "CellTwo") as! customTableViewCellTwo

if (..something...) { 
    cellOne.mLabel = "hey"
    return cellOne
}

else if (..another condition..) {
    cellTwo.mButton.layer.cornerRadius = 5
    return cellTwo
}
return UITableViewCell()

I hope it helps

Upvotes: 0

Gaurang
Gaurang

Reputation: 747

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")

Upvotes: 9

derdida
derdida

Reputation: 14904

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.

Upvotes: -4

Imanou Petit
Imanou Petit

Reputation: 92419

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.

Upvotes: 6

Related Questions