I want to mark the items in the list with checkmarks. But some kind of error occurs because the checkmark is installed, but not removed.
Why is this happening?
This is a Model:
import UIKit
struct Food: Codable {
var name: String
var isSelected: Bool = false
}
This is a TableViewController:
import UIKit
class SelectFoods: UITableViewController {
var foods = [Food]()
override func viewDidLoad() {
super.viewDidLoad()
foods = loadRealOrDemoData() // Load data
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
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: "selectFood", for: indexPath)
let food = foods[indexPath.row]
cell.textLabel?.text = food.name
// Assign checkmark from the selected item to the cell
if food.isSelected {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
cell.selectionStyle = .none
return cell
}
// MARK: - Select Food
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Create variable and check it.
guard let cell = tableView.cellForRow(at: indexPath) else { return }
//Clean cell format before select
cell.accessoryType = .none
// Get an item
var item = foods[indexPath.row]
// Set checkmark
if item.isSelected == false {
cell.accessoryType = .checkmark
item.isSelected.toggle()
// Remove checkmark
} else {
cell.accessoryType = .none
item.isSelected.toggle()
}
}
}
I use this if condition inside of didSelectRowAt method
That seems to be the critical part of your code.
In your code, item
is a local variable. Changing the property of it does not affect the instance property food
.
Please try something like this:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
foods[indexPath.row].isSelected.toggle()
tableView.reloadRows(at: [indexPath], with: .automatic)
}
UITableView
manages cell selection internally. So, you may need to add some code to make your isSelected
work with such internal selection management, but anyway, please try the code above and tell us what happens.