i\'m trying to return different cells in a tableView. Normally in this case i would return different cells and then return nil at the bottom, but in this case it gives me an
As indicated in a previous answer for a similar question, -tableView:cellForRowAtIndexPath:
must return a UITableViewCell
. So you can't return nil
. However, I would also recommend to avoid returning the following codes at the end of -tableView:cellForRowAtIndexPath:
when you use if else or switch statements inside it:
//bad code design
var cell: UITableViewCell!
return cell
or:
//bad code design
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
return cell
You can do better code than creating an UITableViewCell
instance that is never called just in order to silent Xcode warnings!
So what would be the solution?
The key thing is to be sure that your last possible value for an if else statement is set in else
(not in else if
). In the same way, the key thing is to be sure that your last possible value for a switch statement is set in default:
(not in case XXX:
).
Thus, your code should look like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("CellZero", forIndexPath: indexPath) as UITableViewCell
/* ... */
return cell
} else if indexPath.row == 1 {
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("CellOne", forIndexPath: indexPath) as CellOne
/* ... */
return cell
} else { //set your last indexPath.row case in "else", not in "else if indexPath.row == 2"!!!
switch segment {
case 0:
let cell = tableView.dequeueReusableCellWithIdentifier("CellTwo", forIndexPath: indexPath) as CellTwo
/* ... */
return cell
case 1:
let cell = tableView.dequeueReusableCellWithIdentifier("CellThree", forIndexPath: indexPath) as CellThree
/* ... */
return cell
default: //set your last segment case in "default:", not in "case 2:"!!!
let cell = tableView.dequeueReusableCellWithIdentifier("CellFour", forIndexPath: indexPath) as CellFour
/* ... */
return cell
}
}
//No need for a fictive "return cell" with this code!!!
}
If segment
is not an optional, thanks to tuples, you can even reduce the previous code to this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
switch (indexPath.row, segment) {
case (0, _):
let cell = tableView.dequeueReusableCellWithIdentifier("CellZero", forIndexPath: indexPath) as UITableViewCell
/* ... */
return cell
case (1, _):
let cell = tableView.dequeueReusableCellWithIdentifier("CellOne", forIndexPath: indexPath) as CellOne
/* ... */
return cell
case (2, 0):
let cell = tableView.dequeueReusableCellWithIdentifier("CellTwo", forIndexPath: indexPath) as CellTwo
/* ... */
return cell
case (2, 1):
let cell = tableView.dequeueReusableCellWithIdentifier("CellThree", forIndexPath: indexPath) as CellThree
/* ... */
return cell
default: //case (2, 2)
let cell = tableView.dequeueReusableCellWithIdentifier("CellFour", forIndexPath: indexPath) as CellFour
/* ... */
return cell
}
}