Search code examples
iosuitableviewswiftbemsimplelinegraph

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


Solution

  • 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 don't know, but to fix it what you need to do is to dequeue the cell inside your if blocks like so.

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