irkinosor
irkinosor

Reputation: 776

How can I keep a cell selected while scrolling the tableView?

I want a cell to remain selected when it is touched and if it is touched again to be deselected. This is my code which is not working:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let selectedCell = tableView.cellForRowAtIndexPath(indexPath)
    if let value = selectedCell?.selected.boolValue {
        if !value {
            print("cell was selected and will remain selected") 
            selectedCell?.selected = true
        } else {
            print("cell is deselected")
            selectedCell?.selected = false
        }
    }
}

How can I implement this?

Upvotes: 2

Views: 3224

Answers (5)

Matthew Hallatt
Matthew Hallatt

Reputation: 1380

My understanding is that cell selection and deselection is handled by default - you shouldn't have to mess with the selected values of the cells yourself!

You may need to update some elements of the cell in the tableView:cellForRowAtIndexPath: method based on the selected state.

If this isn't working out of the box and/or you want to customise this behaviour, you should look at the tableView:didDeselectRowAtIndexPath: method as well. The combination of these two methods should allow you to control the selected state completely.

Upvotes: 0

irkinosor
irkinosor

Reputation: 776

alright, this is how I manage to do it declaring a var selectedIndexPath: NSIndexPath? and then in the didSelectRowAtindexPath did the following:

            if selectedIndexPath == indexPath {
                tableView.deselectRowAtIndexPath(indexPath, animated: true)
                selectedIndexPath = nil
            }else{
                tableView.selectRowAtIndexPath(indexPath, animated: true, scrollPosition: .None)
                selectedIndexPath = indexPath
            }

Upvotes: 0

MrDank
MrDank

Reputation: 2050

You can set the default tag value of each cell in cellForRowAtIndex as cell.tag = 0

Inside the didSelectRowAtIndexPath function you can do something like this

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

   let selectedCell = tableView.cellForRowAtIndexPath(indexPath)
   if selectedCell.tag == 0 {
       print("cell was selected")
       selectedCell.tag = 1
   }
   else {
       print("cell was deselected")
       selectedCell.tag = 0
   }

}

Upvotes: 0

Russell
Russell

Reputation: 5554

if all you ever have is one selected row at a time, then even without a data model (which you should have), you could have an attribute of the ViewController selectedRowIndex which is updated each time you select a row, and refresh the tableView - as part of the cellForRowAtIndexPath you can check if indexPath.row == selectedRowIndex and make whatever visual changes you need

define an attribute to track the currently selected row

var selectedRowIndex = -1

then update that attribute when the user selects a row

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
    // build up an array of rows to be refreshed
    // the previously selected row (if any)
    // and the current one
    var indexPaths : [NSIndexPath] = []

    // if a row was previous selected, clear the display
    if selectedRowIndex != -1
    {
        indexPaths.append(NSIndexPath(forRow: selectedRowIndex, inSection: 0))
    }

    selectedRowIndex = indexPath.row
    indexPaths.append(NSIndexPath(forRow: selectedRowIndex, inSection: 0))

    // now refresh just those rows
    self.tableView.reloadRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.None)

}

and then do something with it when the row is redrawn

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyCell

    if indexPath.row == selectedRowIndex
    {
        cell.backgroundColor = UIColor.greenColor()
    }
    else
    {
        cell.backgroundColor = UIColor.whiteColor()
    }
      // everything else
    return cell
}

Upvotes: 0

dimpiax
dimpiax

Reputation: 12667

Remember rules:

  • Store cells data in model
  • UITableViewController only for visualisation

On your code, make storing selected value, for example in array, by indexPath.row

Upvotes: 1

Related Questions