Filipe Louro
Filipe Louro

Reputation: 87

Tableview scroll changes selection

i looked at a couple of StackOverflow questions related with this one but it seems in not getting yet the concept very well.

I have a tableview with a couple of cells that i fill using a enum. When i scroll down the rows another row lower in the table gets selected. I have the following methods implemented:

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

    var cell = tableView.dequeueReusableCellWithIdentifier("activityCell", forIndexPath: indexPath) as UITableViewCell

    cell.textLabel?.text = activities[indexPath.item].rawValue;

    return cell;
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    var cell = tableView.cellForRowAtIndexPath(indexPath);
    cell?.selected = true;

}

I understand that the cells are reusable but i was not able to understand properly this concept and how it applies.

Can you give me some help?

Cheers

Upvotes: 2

Views: 1794

Answers (2)

Alen Alexander
Alen Alexander

Reputation: 735

As Byron suggested, we can handle this scenario by saving the selected index paths in an array and removing them from array when unselected.

var indexArray  : [NSIndexPath]?

Initialise the indexArray before loading the table as

self.indexArray = []

Cell selection & de-selection must be reflected in the indexArray with the help of delegate functions as:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
                cell.accessoryType = .checkmark
                self.indexArray?.append(indexPath as NSIndexPath)
        }
       }

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {

        if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
            cell.accessoryType = .none
            if let pos = self.indexArray?.index(of: indexPath as NSIndexPath)
            {
                self.indexArray?.remove(at: pos)
            }
        }
       }

Now, when cellForRowAtIndexpath function gets called for each row, check whether the current indexPath is present in our indexArray. If so, the cell is already selected, else, the cell is in unselected state & perform corresponding tasks on the cell.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier") as! YourTableViewCell

    if (self.indexArray?.contains(indexPath as NSIndexPath))!
    {
        cell.accessoryType = .checkmark
    }
    else
    {
        cell.accessoryType  = .none
    }
    return cell
}

Upvotes: 0

Lyndsey Scott
Lyndsey Scott

Reputation: 37300

If you're going to reuse your cells, setting the cell as selected in didSelectRowAtIndexPath at indexPath in the way that you've done will make the reused cell's also reflect the changed selected property. Instead, I'd recommend adding a boolean selected property to your activity object such that the selection changes can be made in cellForRowAtIndexPath:, ex:

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

    var cell = tableView.dequeueReusableCellWithIdentifier("activityCell", forIndexPath: indexPath) as UITableViewCell

    cell.textLabel?.text = activities[indexPath.item].rawValue
    cell?.selected = activities[indexPath.item].selected
    return cell;
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    activities[indexPath.item].selected = true
    self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)

}

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {

    activities[indexPath.item].selected = false
    self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)

}

Upvotes: 2

Related Questions