Search code examples
iosswiftuitableviewvariablesdowncast

swift variable type won't change after downcast if the variable has been declared?


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!
    ......
}

Solution

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