Wayne Wayne - 4 months ago 26
Swift Question

TableView selected cells - checkmarks disappear when scrolled out of sight and new cell checked

I have a tableView that I use a checkmark. I have a function that puts the contents of the cell into textField and similarly removes the text from the text field when it is unchecked.

It seems to work fine but if I check a cell and want to check a cell thats not visible (IOW) I need to scroll the tableView, the cell that was checked (is now not visible) seems to uncheck itself (Only when I check a new visible cell).

The multi select works with visible cells only.

Here is my code:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)
let row = indexPath.row
cell.textLabel?.text = painArea[row]
cell.accessoryType = .None
return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//selectedRow = indexPath
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
let cell = tableView.cellForRowAtIndexPath(indexPath)
if cell!.accessoryType == .Checkmark {
cell!.accessoryType = .None
} else {
cell!.accessoryType = .Checkmark
}
populateDescription()
print(painArea[row])
}

var painDescription = ["very sore"]

func populateDescription() {
painDescription.removeAll()
severityText.text = ""
for cell in tableView.visibleCells {
if cell.accessoryType == .Checkmark {
painDescription.append((cell.textLabel?.text)! + " ")
}
var painArea = ""
var i = 1

while i <= painDescription.count {
painArea += painDescription[i-1] + "~"
i = i + 1
}
severityText.text = painArea

}


I hope I am explaining myself adequately. I don't want the non visible cells to be unchecked and thus removed from my text field unless I uncheck it.

Any ideas would be most appreciated.

Kind regards

Wayne

Answer

It is happing because of reusability of Cell. Instead of setting Checkmark in didSelect try to set in the cellForRowAtIndexPath. Also you need to create model class like this to solve your problem

class ModelClass: NSObject {
    var isSelected: Bool = false
    //Declare other property that you are using cellForRowAtIndexPath
}

Now check this isSelected in cellForRowAtIndexPath like below.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) 
    let row = indexPath.row 
    let modelClass = painArea[row]
    cell.textLabel?.text = modelClass.name
    if modelClass.isSelected {
        cell.accessoryType = .Checkmark
    }
    else {
        cell.accessoryType = .None
    }
    return cell 
}

Now change your didSelect like this

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var modelClass = painArea[indexPath.row]
    modelClass.isSelected = !modelClass.isSelected
    self.tableView.reloadData()
    populateDescription()
    print(painArea[row])
}

Hope this will help you.