John Luke Garofalo
John Luke Garofalo

Reputation: 140

Custom UITableviewCells displayed correctly but only one in the section is the correct class

I apologize for the poorly worded question but I simply cannot think of why/how to describe this bug in a short manner.

Basically I have a table view controller displaying two sections, each with a respective custom UITableViewCell subclass. They are displayed perfectly, with the correct model data.

The problem arises when I hit the "done" button, my program traverses through all the cells, gathering the data from each cell and updating the model. The first section goes off without a hitch... but the second section is where trouble hides. The first cell of this section can be casted into the proper subclass, yet any other additional cells don't pass this conditional test and their reuse identifier is nil. I tried checking the cells when they're dequeued but they are being created/reused properly. My code is below and any suggestions will aid my sanity.

Here is the part of my helper function that traverses the cells:

    for i in 0..<tableView.numberOfSections {
        for j in 0...tableView.numberOfRowsInSection(i) {
            let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: j, inSection: i))

                // This section seems to work fine
                if(i == 0){
                    if let gradeCell: PercentTableViewCell = cell as? PercentTableViewCell {
                        print("retrieveCellInfo: gradeCell - \(gradeCell.getPercent())")
                        newPercentages.append(gradeCell.getPercent())
                    }
                } else if (i == 1){
                    print("Else if i == 1 : j == \(j) : \(cell?.reuseIdentifier!)") // Prints "category" for the first cell and "nil" for any other

                    // This is the cast conditional that only lets one cell through
                    if let catCell = cell as? EditTableViewCell{
                        newCategories.append(Category(name: catCell.category!, weight: catCell.weight!, earned: catCell.earned!, total: catCell.total!))
                    }
                }
        }
    }

Here is my delegate function which works perfectly as far as I can tell. As I said, the UI is displayed correctly:

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

    if(indexPath.section == 0){
        /* Grade Parameter Cells */
        let cell: PercentTableViewCell = tableView.dequeueReusableCellWithIdentifier("gradeParam", forIndexPath: indexPath) as! PercentTableViewCell

        var gradePercentages = course?.getGradePercentages()

        // Make sure percentages array is sorted correctly
        gradePercentages?.sortInPlace() {
            return $0 > $1
        }

        // Update cell's member variables
        cell.initialize(letters[indexPath.row], percent: gradePercentages![indexPath.row])

        return cell

    } else {
        /* Category Cells */
        let catcell: EditTableViewCell = tableView.dequeueReusableCellWithIdentifier("category", forIndexPath: indexPath) as! EditTableViewCell

        let category = categories![indexPath.row]

        catcell.setLabels(category.name, earned: category.earned, total: category.total, weight: category.weight)

        return catcell
    }
}

Upvotes: 0

Views: 49

Answers (1)

Paulw11
Paulw11

Reputation: 114866

The problem arises when I hit the "done" button, my program traverses through all the cells, gathering the data from each cell and updating the model

This is your problem. Your cells should reflect your data model, they cannot be relied upon to hold data as once the cell is offscreen it may be re-used for a row that is onscreen.

If data is updated by the user interacting with the cells then you should update your data model as they do that. You can use a temporary store if you don't want to commit changes immediately.

Upvotes: 1

Related Questions