0

I intended to downcast a UITableViewCell to different subclasses based on which section it is in.

Suppose a subclass of UITableViewCell is CellOne and it has a var nameLabel. In one case, I downcast (as!) the UITableViewCell returned by dequeueReusableCellWithIdentifier(_:_:) to CellOne and assigned it to cell, a variable declared as var cell = UITableViewCell() outside the switch block.

But after that, cell can't access nameLabel that is held by CellOne instance. I got the error message: "Value of type 'UITableViewCell' has no member nameLabel".

So it seems cell has not been downcasted to UITableViewCell's subclass.

Is there any way that cell can access nameLabel (after declared outside the block)? Can a variable be downcasted to another type by assigning a subclass instance to it after it has been declared?

Thank you very much for your time.


Here is my code:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = UITableViewCell()

    switch indexPath.section {
    case 0:
        cell = tableView.dequeueReusableCellWithIdentifier("cellOne", forIndexPath: indexPath) as! CellOne
        cell.nameLabel.text = "one" // Error: Value of type 'UITableViewCell' has no member 'nameLabel'
    case 1:
        cell = tableView.dequeueReusableCellWithIdentifier("cellTwo", forIndexPath: indexPath) as! CellTwo
    ...... // Other cases
    }

    return cell
}

And code for CellOne:

class CellOne: UITableViewCell {
    @IBOutlet weak var nameLabel: UILabel!
    ......
}
ninikikki
  • 3
  • 2

2 Answers2

0

The problem is where you declared the variable cell you specifically said that its a UITableViewCell,so you will have issue to downcast it as yourCustomCell.

change this :

  var cell = UITableViewCell()

Based on your comment you want to use multiple custom cells

I think you should declare those customs cells within the case code block

 switch indexPath.section 
{
  case 0:
    let cell = tableView.dequeueReusableCellWithIdentifier("cellOne", forIndexPath: indexPath) as! CellOne
      cell.nameLabel.text = "one"
  case 1:
     let secondCell = tableView.dequeueReusableCellWithIdentifier("cellTwo", forIndexPath: indexPath) as! CellTwo
       // do whatever you want 
}
Lamour
  • 3,002
  • 2
  • 16
  • 28
  • Hi Lamour, thank you for your answer! I didn't declare 'cell' as 'CellOne' because it may be downcasted to other subclasses of UITableViewCell (such as CellTwo, CellThree...) based on which section it is in. So I couldn't declare it as 'CellOne'. I'll edit the question to make it clearer. – ninikikki Oct 06 '15 at 18:50
  • so if you are using other custom cell you should just declare in the same code block as the case – Lamour Oct 06 '15 at 18:51
  • I don't wanna repeat "return cell" for many times. But I guess I don't have another option =) Thanks a lot! – ninikikki Oct 06 '15 at 18:53
  • best guess is to use declare that cell variable within the case block – Lamour Oct 06 '15 at 19:05
0

I find it's better to make your cells more generic to they can work in more than one 'section'. ie. instead of 'CellOne' create your cell as 'NameCell' which can be used across all sections of your table.

Cells should be reusable.

let nameCell = tableView.dequeueReusableCellWithIdentifier("nameCell") as! NameCell

switch indexPath.section{
case 0: 
  nameCell.nameLabel.text = "name1"
break
case 1:
  nameCell.nameLabel.text = "name2"
break
...
default:
  ...
}
JoshR604
  • 155
  • 1
  • 5
  • Hi JoshR604, thank you! I'd like different styles and elements for cells in different sections so I wanna assign different subclasses to it. – ninikikki Oct 06 '15 at 19:07