可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am sure this question have been asked before but I can't find an answer that solves my problem with nested if-else and switch-case logic.
I have a UITableView
with two sections, each sections has two custom cells. That is it it. 4 cells. But no matter what I do I get "Missing return in a function expected to return UITableViewCell
"
Question How can I change this setup so that I get an else statement at the bottom that will satisfy swift logic?
Any help would be very much appreciated
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if indexPath.section == 0{ switch (indexPath.row) { case 0: let cell0: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath) as! SettingsCell cell0.backgroundColor = UIColor.redColor() break case 1: let cell1: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! SettingsCell cell1.backgroundColor = UIColor.whiteColor() break default: break } } if indexPath.section == 1{ switch (indexPath.row) { case 0: let cell10: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell10", forIndexPath: indexPath) as! SettingsCell cell10.backgroundColor = UIColor.redColor() break case 1: let cell11: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell11", forIndexPath: indexPath) as! SettingsCell cell11.backgroundColor = UIColor.whiteColor() break default: break } } }
回答1:
- Declare the cell at the start of the method,
- assign a value to the cell depending on section and row number,
- throw a
fatalError()
in all cases that "should not occur", - return the cell.
Also note that the break
statements are not needed. The default behavior in Swift is not to fall through to the next case.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell: SettingsCell switch(indexPath.section) { case 0: switch (indexPath.row) { case 0: cell = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.redColor() case 1: cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.whiteColor() default: fatalError("Unexpected row \(indexPath.row) in section \(indexPath.section)") } case 1: switch (indexPath.row) { case 0: cell = tableView.dequeueReusableCellWithIdentifier("cell10", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.redColor() case 1: cell = tableView.dequeueReusableCellWithIdentifier("cell11", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.whiteColor() default: fatalError("Unexpected row \(indexPath.row) in section \(indexPath.section)") } default: fatalError("Unexpected section \(indexPath.section)") } return cell }
The fatalError()
error function is marked as @noreturn
, so the compiler knows that program execution will not continue from the default cases. (This also helps to find logic errors in the program.)
The compiler verifies that a value is assigned to cell
in all other cases.
The possibility to initialize a constant (let cell ...
) in this way is new in Swift 1.2.
Alternatively, you can create a cell and return it "immediately" in each case:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { switch(indexPath.section) { case 0: switch (indexPath.row) { case 0: let cell = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.redColor() return cell case 1: let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.whiteColor() return cell default: fatalError("Unexpected row \(indexPath.row) in section \(indexPath.section)") } case 1: switch (indexPath.row) { case 0: let cell = tableView.dequeueReusableCellWithIdentifier("cell10", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.redColor() return cell case 1: let cell = tableView.dequeueReusableCellWithIdentifier("cell11", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.whiteColor() return cell default: fatalError("Unexpected row \(indexPath.row) in section \(indexPath.section)") } default: fatalError("Unexpected section \(indexPath.section)") } }
Again, calling fatalError()
solves the "missing return expected" compiler error.
This pattern can be useful if there are different kinds of cells (with different classes) created in each case.
回答2:
You must return a cell, if the section is number 2 this methods won't be returning anything, well it's the case when u specify secitons more than two. Solution
- Second "if" will be "else" part
- Limit number of section
回答3:
You're missing in you method the return statement.
Example with return statement.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if indexPath.section == 0{ switch (indexPath.row) { case 0: let cell: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.redColor() break case 1: let cell: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.whiteColor() break default: let cellId: NSString = "Cell" var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellId) as UITableViewCell break } } if indexPath.section == 1{ switch (indexPath.row) { case 0: let cell: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell10", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.redColor() break case 1: let cell: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell11", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.whiteColor() break default: let cellId: NSString = "Cell" var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellId) as UITableViewCell break } } return cell }
回答4:
you can use else if like this :
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if indexPath.section == 0{ switch (indexPath.row) { case 0: let cell: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.redColor() break case 1: let cell: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.whiteColor() break default: break } else if indexPath.section == 1{ switch (indexPath.row) { case 0: let cell: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell10", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.redColor() break case 1: let cell: SettingsCell! = tableView.dequeueReusableCellWithIdentifier("cell11", forIndexPath: indexPath) as! SettingsCell cell.backgroundColor = UIColor.whiteColor() break default: break } } return cell } }
it may help you try it