-2

I have a tableview where not all of the cells are visible at once. I am trying to make it so that when a row is tapped it adds a checkmark accessory to the cell. My issue is that it adds it to other rows as well. In my table view there are 4 rows fully showing and a fifth one barely showing. If I check the first box it will then add a check mark to every fifth box (e.g. indexPath.row = 0,5,10,15...) despite the indexPath.row being different.

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

     let cell: DropDownMenuCell = tableView.dequeueReusableCellWithIdentifier("DropDownMenuCell", forIndexPath: indexPath) as! DropDownMenuCell
     cell.dropDownCellLabel?.text = DropDownItems[indexPath.row].Name
     return cell

}


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

    let selectedCell: DropDownMenuCell = tableView.cellForRowAtIndexPath(indexPath) as! DropDownMenuCell
    print(indexPath.row)
    if selectedCell.accessoryType == .None {
        selectedCell.accessoryType = .Checkmark
    } else {
        selectedCell.accessoryType = .None
    }

}

Edit: Apologies for the duplicate, my initial search for this question didn't show the other question. I got a working answer here in swift already or I would try and go through the objective c post to solve my problem.

Frodgers
  • 95
  • 2
  • 12
  • 2
    possible duplicate of [Multiple checkMark when row selected in UITableView IOS](http://stackoverflow.com/questions/23727255/multiple-checkmark-when-row-selected-in-uitableview-ios) – Dmytro Hutsuliak Sep 21 '15 at 14:12
  • Tableview cells are re-used. You need to maintain an array of indexes of the cells that have been tapped and set the checkmark in `tableView:cellForRowAtIndexPath:` based on your array. If you search StackOverflow you will find other questions about cell re-use. – Robotic Cat Sep 21 '15 at 14:12

2 Answers2

1

Maintain in your Data source which cell is to be selected.

Then in cellForRowAtIndexPath:

if (DropDownItems[indexPath.row].isSelected) {
    cell.accessoryType = .Checkmark
} else {
    cell.accessoryType = .None
}

and in your didSelectRowAtIndexPath Method:

if(DropDownItems[indexPath.row].isSelected) {
    DropDownItems[indexPath.row].isSelected = false
} else {
    DropDownItems[indexPath.row].isSelected = true
}

self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)
Ishan Handa
  • 2,271
  • 20
  • 25
0

In Swift 3, this should help:

import UIKit

class ViewController: UITableViewController {

let foods = ["apple", "orange", "banana", "spinach", "grape"]

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int

{
    return foods.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
    UITableViewCell
{
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = foods[indexPath.row]
    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
    if tableView.cellForRow(at: indexPath)?.accessoryType == UITableViewCellAccessoryType.checkmark
    {
        tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.none
    }
    else
    {
        tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.checkmark
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}