user3185748 user3185748 - 5 months ago 291
Swift Question

Load Multiple Prototype Cells into UITableView

I currently have a UITableView containing 2 rows of a custom cell. I recently added a second prototype cell to my storyboard and have been attempting to add it to my UITableView with no success. My cellForRowAtIndexPAth method is as follows:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell: FlightsDetailCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as FlightsDetailCell

cell.userInteractionEnabled = false

if indexPath.section == 0 {

cell.graphView.enableBezierCurve = true
cell.graphView.enableReferenceYAxisLines = true
cell.graphView.enableYAxisLabel = true
cell.graphView.colorYaxisLabel = UIColor.whiteColor()
cell.graphView.delegate = UIApplication.sharedApplication().delegate as BEMSimpleLineGraphDelegate
cell.graphView.dataSource = UIApplication.sharedApplication().delegate as BEMSimpleLineGraphDataSource
return cell
}

if indexPath.section == 1 {
cell.graphView.enableBezierCurve = true
cell.graphView.enableReferenceYAxisLines = true
cell.graphView.enableYAxisLabel = true
cell.graphView.colorYaxisLabel = UIColor.whiteColor()
cell.graphView.delegate = self
cell.graphView.dataSource = self
return cell
}

if indexPath.section == 2 {

let cell2: FlightsInformationCell = tableView.dequeueReusableCellWithIdentifier("Cell2", forIndexPath: indexPath) as FlightsInformationCell
cell2.userInteractionEnabled = false

return cell2
}

return cell

}


Section 0 and Section 1 correctly load the prototype cell with ID "Cell" but when I go to load section 2 I get another instance of the first prototype cell less any data as it hasn't been assigned a delegate or dataSource. Otherwise the cells are set up identically with ID's of "Cell" and "Cell2" respectively but I can't seem to access "Cell2".

Additional Clarification: I have 2 prototype cells in my storyboard, they are both set up the same in that they both have their identifiers labeled in the same boxes, inherit from their own classes and have been declared the same in my UITableView. As for the delegates and dataSources, my original prototype cell holds a graph (uses BEMSimpleLineGraph), each instance of this cell has it's own delegate and datasource and shown in the above code for actions 0 and 1.

The first cell pictured below (in grey) is the original cell that holds a graph and cell2 is just below it in white.

enter image description here

Answer

I set up a test app using code similar to what you have in cellForRowAtIndexPath, and I got the same results. Even though the code in my if indexPath.section == 2 clause was entered, the cell that was returned looked the same as my first two cells (but with no string in the label); this is despite the fact that I set it up with different sub views, and a log showed it to be the correct class for what I wanted for section 2. Why this happens, I can't figure out, but the way to fix it is to not dequeue a cell outside your if blocks.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {


cell.userInteractionEnabled = false

if indexPath.section == 0 {
    let cell: FlightsDetailCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as FlightsDetailCell
    cell.graphView.enableBezierCurve = true
    cell.graphView.enableReferenceYAxisLines = true
    cell.graphView.enableYAxisLabel = true
    cell.graphView.colorYaxisLabel = UIColor.whiteColor()
    cell.graphView.delegate = UIApplication.sharedApplication().delegate as BEMSimpleLineGraphDelegate
    cell.graphView.dataSource = UIApplication.sharedApplication().delegate as BEMSimpleLineGraphDataSource
    return cell
}

else if indexPath.section == 1 {
    let cell: FlightsDetailCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as FlightsDetailCell
    cell.graphView.enableBezierCurve = true
    cell.graphView.enableReferenceYAxisLines = true
    cell.graphView.enableYAxisLabel = true
    cell.graphView.colorYaxisLabel = UIColor.whiteColor()
    cell.graphView.delegate = self
    cell.graphView.dataSource = self
    return cell
}

else {
    let cell2: FlightsInformationCell = tableView.dequeueReusableCellWithIdentifier("Cell2", forIndexPath: indexPath) as FlightsInformationCell
    cell2.userInteractionEnabled = false
    return cell2
}

}

This could be further refactored to take out repetitive code, but this should work...

Comments