Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
}
like image 347
gamerChristian Avatar asked Oct 01 '14 12:10

gamerChristian


2 Answers

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")
like image 182
Gaurang Avatar answered Oct 22 '22 19:10

Gaurang


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.

like image 26
Imanou Petit Avatar answered Oct 22 '22 20:10

Imanou Petit