Mwi Ti Mwi Ti - 4 months ago 6
iOS Question

Switch statement for the tag property of a view

I'm trying to set up a tableview that has 2 cells. Both cells have their own classes and they have their own methods to configure them. In code, when i get to the cellforrowatindexpath method, i get stuck. I can only dequeue one of the cells and call it's methods, which means the other cell won't configured. I want to configure both. Here's what i'm (currently) trying in the cellforrow method:

let cells = [tableView.viewWithTag(1), tableView.viewWithTag(2)]



for view in cells {

var reuseIdentifier = "cellID"


switch view?.tag {
case 1: // error occurs here
reuseIdentifier = "storyCell"
let storyCell1 = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! StoryCell1

storyCell1.theCategory.text = newsItem.storyCategory
storyCell1.theTitile.text = newsItem.titleText
storyCell1.firstParagraph.text = newsItem.paragraph1

case 2: // error occurs here too
reuseIdentifier = "storyCell2"
let storyCell2 = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! StoryCell2
storyCell2.configureCell(newsItem)


default:

}


in the storyboard, i have given both those cells tags of 1 and 2 respectively, hence the array at the very beginning. I have 2 problems with this approach.


  1. I can't use it because the switch statement is throwing me an error: Expression pattern of type 'Int' cannot match values of type 'Int?'

  2. even if it were to not have the error above, i can still only return one cell at the end of the method.



any help on my approach or a different, better way to handle this would be appreciated. Thanks!

EDIT:

Since I'm sure i've added the tag property i force unwrapped the view!.tag property and the error goes away. So, the 2nd question now remains.

Answer

I don't really get what you want to do here.

What I think you're trying to do, is to configure and return two cells in the tableView(_:cellForRowAtIndexPath:) method. If you really want to do this, you're totally doing it wrong.

The table view's data source methods asks questions. And your job is to answer those questions by returning a value. For example, numberOfSectionsInTableView(_:) asks you how many sections should there be. An example answer might be return 1, return 10 etc.

Similarly, tableView(_:cellForRowAtIndexPath:) asks

What should be the cell that should be shown in the section and row specified by the index path?

And you answer by returning a UITableViewCell. You can't return two cells because it is asking you to provide a cell to be displayed at that specific section and row. If you gave it two cells to display, how can the table view display them? It doesn't make sense! Each row in the table view can only display one cell!

Therefore, instead of giving tags to the cells, use the indexPath parameter to decide which cell to create.

Let's say you want the first row to display the cell with the identifier "storyCell". And you want the second row to display the cell with the identifier "storyCell2". And your table view has only one section. You can just do this:

    switch indexPath.row {
    case 0:
        reuseIdentifier = "storyCell"
        let storyCell1 = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! StoryCell1

        storyCell1.theCategory.text = newsItem.storyCategory
        storyCell1.theTitile.text = newsItem.titleText
        storyCell1.firstParagraph.text = newsItem.paragraph1
        return storyCell1

    case 1:
        reuseIdentifier = "storyCell2"
        let storyCell2 = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! StoryCell2
        storyCell2.configureCell(newsItem)
        return storyCell2

    default:
        // this shouldn't be reached if you do your other data source methods correctly
        return UITabeViewCell()
    }

And you should delete these nonsense:

let cells = [tableView.viewWithTag(1), tableView.viewWithTag(2)]



for view in cells {

    var reuseIdentifier = "cellID"