Reputation: 332
I have a UITableView
containing about 30 cells. The user is only able to select one. Once a cell is selected it shows a checkmark. But the problem is whenever I scroll down the UITableView
it shows cells i never clicked with a checkmark beside them. What is the proper way to fix this?
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return breedNameArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Bcell")
let cell = tableView.dequeueReusableCell(withIdentifier: "Bcell", for: indexPath)
//cell.accessoryType = UITableViewCell.AccessoryType.checkmark
cell.textLabel?.text = breedNameArray[indexPath.item]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
tableView.register(UINib(nibName: "BBcell", bundle: nil), forCellReuseIdentifier: "Cell")
//let cell = tableView.dequeueReusableCell(withIdentifier: "Breeds", for: indexPath)
//tableView.deselectRow(at: tableView.indexPathForSelectedRow!, animated: true)
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Bcell")
//let cell = tableView.dequeueReusableCell(withIdentifier: "Breeds", for: indexPath)
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
Upvotes: 0
Views: 102
Reputation: 136
The reason you are seeing cells getting checkmarks when scrolling is because the call to tableView.dequeueReusableCell(withIdentifier:"Bcell", for: indexPath) in cellForRowAt reuses already allocated UITableViewCell objects that have the identifier "Bcell". The UITableView does not automatically reset the properties of the reused UITableViewCell objects when reused in this way.
Since you are only allowing one UITableViewCell to be selected at a time, a simple solution would be to add a local variable to keep track of the selected IndexPath, and then use the local variable to set the accessoryType accordingly in cellForRowAt. Here is the code to illustrate what I mean:
// The local variable to keep track of the selected IndexPath
var selectedIndexPath = IndexPath()
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return breedNameArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Bcell")
let cell = tableView.dequeueReusableCell(withIdentifier: "Bcell", for: indexPath)
// Use selectedIndexPath to set the accessoryType as .checkmark or .none
if indexPath == selectedIndexPath {
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
} else {
cell.accessoryType = UITableViewCell.AccessoryType.none
}
cell.textLabel?.text = breedNameArray[indexPath.item]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Set the selectedIndexPath
selectedIndexPath = indexPath
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
tableView.register(UINib(nibName: "BBcell", bundle: nil), forCellReuseIdentifier: "Cell")
//let cell = tableView.dequeueReusableCell(withIdentifier: "Breeds", for: indexPath)
//tableView.deselectRow(at: tableView.indexPathForSelectedRow!, animated: true)
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
// Un-Set the selectedIndexPath
selectedIndexPath = IndexPath()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Bcell")
//let cell = tableView.dequeueReusableCell(withIdentifier: "Breeds", for: indexPath)
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
Upvotes: 1