First note that
func dequeueReusableCellWithIdentifier(identifier: String, forIndexPath indexPath: NSIndexPath) -> UITableViewCell
is preferred over
func dequeueReusableCellWithIdentifier(identifier: String) -> UITableViewCell?
because – according to the documentation –
This method uses the index path to perform additional configuration based on the cell’s position in the table view.
and because it returns a non-optional UITableViewCell
.
If you just want to return one of the two possible prototype cells
then you don't need to cast at all.
But there is no need to make cell
an optional. You can even
declare it as a constant, this allows the compiler to verify that it is assigned a value exactly once
on each code path.
let cell: UITableViewCell
if condition {
cell = tableView.dequeueReusableCellWithIdentifier("AddSetCell", forIndexPath: indexPath)
} else {
cell = tableView.dequeueReusableCellWithIdentifier("SetCell", forIndexPath: indexPath)
}
// ... set up common properties ...
return cell
If you want to assign specific properties to the different cell types
then you need to cast to the respective type.
Since you define the custom class SetTableViewCell
for the prototype cell with identifier "SetCell" in the Storyboard,
tableView.dequeueReusableCellWithIdentifier("SetCell", forIndexPath: indexPath)
is guaranteed to return an instance of SetTableViewCell
, either by
re-using a cell or by instantiating a new one from the prototype.
This is one of the legitimate use-cases of the
forced cast operator as!
. Or to put it differently: The cast can only
fail if you did not define the prototype cell correctly. That would be
a programming error and should be detected early.
let cell: UITableViewCell
if condition {
let aCell = tableView.dequeueReusableCellWithIdentifier("AddSetCell") as! AddTableViewCell
// ... set up specific properties ...
cell = aCell
} else {
let sCell = tableView.dequeueReusableCellWithIdentifier("SetCell") as! SetTableViewCell
// ... set up specific properties ...
cell = sCell
}
// ... set up common properties ...
return cell
or alternatively with "early return":
if condition {
let aCell = tableView.dequeueReusableCellWithIdentifier("AddSetCell") as! AddTableViewCell
// ... set up properties ...
return aCell
} else {
let sCell = tableView.dequeueReusableCellWithIdentifier("SetCell") as! SetTableViewCell
// ... set up properties ...
return sCell
}
that is a matter of personal choice.
Finally, if you write your condition as
indexPath.row == tableView.numberOfRowsInSection(indexPath.section) - 1
then it will work for all sections, not only the first one.