Missing Return Uitableviewcell

Missing return in a function expected to return 'UITableViewCell', but actually returning twice

You should return a cell. In the above code, if both conditions failed, then nothing will be returned. So a warning raised. Just remove second "if" condition and use else case as follows:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if friendSelector.selectedSegmentIndex == 0 {
print("0")

cell = self.friendsTable.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FriendsTableViewCell


cell.nameLabel.text = friends[indexPath.row]
cell.bacLabel.text = String(friendsBac[indexPath.row])
cell.statusImageView.image = friendsImage[indexPath.row]

return cell

}

else {
print("1")

celladd = self.friendsTable.dequeueReusableCell(withIdentifier: "celladd", for: indexPath) as! FriendsAddTableViewCell

celladd.nameLabel.text = requested[indexPath.row]
celladd.statusImageView.image = UIImage(named: "greenlight")

return celladd


}

}

Missing return in a function expected to return 'UITableViewCell

This is one of those things that the compiler gets over-worried about. The compiler is basically asking you, what if indexPath.row is neither 0 nor 1 nor 2? What to return in that case. As the programmer you know that indexPath.row will always be one of those values, but the compiler doesn't know that.

So you need to return something in the default case, but it does not make sense to return anything, does it? In this case, I would just write:

fatalError("Somehow indexPath.row is an unexpected value.")

This will crash the app if the default case is ever reached. If the default case is ever reached, it probably means there is something wrong with your code (or maybe a bug in the API (unlikely)!), because as you know the table view only has 3 rows. The app should probably crash at this point.

Missing return UITableViewCell

  • 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.

Getting error like Missing return in a function expected to return 'UITableViewCell' in swift

In both cases you have to return something if the if let check fails.

First of all the enum cases are supposed to be named with starting lowercase letter

enum TableSection: Int {
case profileNameAndImage = 0, followAndFollowings, options
}

In numberOfRows return 0 if the check fails – which actually will never happen

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let tableSection = TableSection(rawValue: section) else { return 0 }
switch tableSection {
case .profileNameAndImage, .followAndFollowings:
return 1
case .options:
return ProfileOptionViewModel.allCases.count
}
}

In cellForRow force unwrap the section (the method is not called if numberOfRows is 0) and also force downcast all cells. The code must not crash. If it does it reveals a design mistake.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let tableSection = TableSection(rawValue: indexPath.section)!
switch tableSection {
case .profileNameAndImage:
let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileImageAndNameTableViewCell") as! ProfileImageAndNameTableViewCell
cell.userData = ProfileImageAndNameModel(userName: "John", userId: "12345", userImage: #imageLiteral(resourceName: "bird"))
return cell

case .followAndFollowings:
let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileTableViewCell") as! ProfileTableViewCell
return cell

case .options:
let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileTableViewCell") as! ProfileTableViewCell
cell.profileData = ProfileOptionViewModel(rawValue: indexPath.row)
return cell
}
}

Note that followAndFollowings returns a cell without data. And TableSection.Options.rawValue is 2 but you have 3 sections so it's fine to hard code the return value

func numberOfSections(in tableView: UITableView) -> Int {
return 3
}

Is there a way to not return a cell after a condition in UITableView?

I am afraid that the only acceptable solution is to do that:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

// Here is where I add the code to calculate which cells should appear, though it's not important for this example

if condition {
return cell
}

// return empty cell
return UITableViewCell()
}


Related Topics



Leave a reply



Submit