Can not return cell in cellForRowAtIndexPath

I am trying to return different cells in a tableView. Usually in this case I would return different cells and then return zero at the bottom, but in this case it gives me an error too. I also tried to return an empty cell, but also gives me an error.

What i tried

return nil 

and

  var cell: UITableViewCell! return cell 

but both returned errors. How can i fix this?

cellForRowAtIndex

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if indexPath.row == 0 { let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("imageCell", forIndexPath: indexPath) as UITableViewCell var imageFile = cell.viewWithTag(100) as PFImageView imageFile.image = itemFile cell.selectionStyle = UITableViewCellSelectionStyle.None return cell } else if indexPath.row == 1 { let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("segmentCell", forIndexPath: indexPath) as UITableViewCell var titleLabel = cell.viewWithTag(101) as UILabel? titleLabel?.text = itemTitle let segmentControl = cell.viewWithTag(102) as UISegmentedControl segmentControl.selectedSegmentIndex = segment segmentControl.setTitle("Beskrivelse", forSegmentAtIndex: 0) segmentControl.setTitle("Sælger", forSegmentAtIndex: 1) segmentControl.setTitle("Lokation", forSegmentAtIndex: 2) segmentControl.tintColor = UIColor(rgba: "#619e00") var font = UIFont(name: "Lato-Regular", size: 11) var attributes:NSDictionary = NSDictionary(object: font , forKey: NSFontAttributeName) segmentControl.setTitleTextAttributes(attributes, forState: UIControlState.Normal) segmentControl.addTarget(self, action: "segmentAction:", forControlEvents: .ValueChanged) cell.selectionStyle = UITableViewCellSelectionStyle.None return cell } else if indexPath.row == 2 { switch segment { case 0: let cell = tableView.dequeueReusableCellWithIdentifier("CellZero", forIndexPath: indexPath) as DescViewCell return cell case 1: let cell = tableView.dequeueReusableCellWithIdentifier("CellOne", forIndexPath: indexPath) as SellerViewCell return cell case 2: let cell = tableView.dequeueReusableCellWithIdentifier("CellTwo", forIndexPath: indexPath) as LocationViewCell return cell default: break } } var cell: UITableViewCell! return cell } 
+1
source share
4 answers

You should not return nil from cellForRowAtIndexPath. You should always return a valid cell.

  var cell: UITableViewCell! 

This line of code does not create any cell, it is just a UITableViewCell variable with nil content, you need to assign it a value:

 var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell return cell 
+1
source

As indicated in the previous answer for a similar question , -tableView:cellForRowAtIndexPath: should return a UITableViewCell . Therefore, you cannot return nil . However, I would also recommend not returning the following codes at the end of -tableView:cellForRowAtIndexPath: if you use if else or switch in 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 create an instance of UITableViewCell that is never called just to turn off Xcode warnings!

So what would be the solution?

The main thing is that your last possible value for the if else statement is set to else (not to else if ). It is equally important to note that your last possible value for the switch statement is set to default: (not in case XXX: .

So 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 optional, thanks to tuples you can even reduce the previous code:

 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 } } 
+5
source

You need to declare the cell in front of your if...then logic, and then return it after. You do not need to initialize the cell if you use var :

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell: UITableViewCell! if indexPath.row == 0 { cell = tableView.dequeueReusableCellWithIdentifier("imageCell", forIndexPath: indexPath) as UITableViewCell // ... } else if indexPath.row == 1 { cell = tableView.dequeueReusableCellWithIdentifier("segmentCell", forIndexPath: indexPath) as UITableViewCell // ... } else if indexPath.row == 2 { // ... } return cell } 

(Just make sure you catch all cases - if your return cell is without initialization, you will get a runtime error.)

+1
source

You only declare the last var cell: UITableViewCell! - you do not initialize it. You need to do something like

 var cell = UITableViewCell(style: someStyle, reuseIdentifier: someID) return cell 
0
source

Source: https://habr.com/ru/post/976104/


All Articles