Reputation: 140
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
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