Reputation: 55
I'm having an issue where when I'm selecting the cell for e.g at index 3 , it selecting cells below also at random indexes. Check and Uncheck cell is working but for some reasons when selecting a cell it is selecting other cells as well. My array is returning 120 rows in total. I have selected multiple touch. Thank you for the help.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return arrayVerbCount.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MesTalentsChoixCell
cell.verb!.text = arrayVerbCount[indexPath.row].verb
if cell.isSelected
{
cell.isSelected = false
if cell.accessoryType == UITableViewCellAccessoryType.none
{
cell.accessoryType = UITableViewCellAccessoryType.checkmark
}
else
{
cell.accessoryType = UITableViewCellAccessoryType.none
}
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let cell = tableView.cellForRow(at: indexPath)
if cell!.isSelected
{
cell!.isSelected = false
if cell!.accessoryType == UITableViewCellAccessoryType.none
{
cell!.accessoryType = UITableViewCellAccessoryType.checkmark
}
else
{
cell!.accessoryType = UITableViewCellAccessoryType.none
}
}
}
My custom cell class:
class MesTalentsChoixCell: UITableViewCell {
@IBOutlet weak var verb: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Upvotes: 3
Views: 679
Reputation: 4738
Make bool array for stability while scrolling i.e.
var arrStatusBool = [Bool]()
Now set value at indexPath.row in didSelectRowAt
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if self.arrStatusBool[indexPath.row]
{
self.arrStatusBool[indexPath.row] = false
}
else
{
self.arrStatusBool[indexPath.row] = true
}
}
And also put this in cellForRowAt to avoid scrolling issue.
if self.arrStatusBool[indexPath.row]
{
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
else
{
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
hope this help!
Upvotes: 1
Reputation: 6565
You should do like this way, this is very much easy solution if there is only one section.
Initialize selectedItems
array like this,
var selectedItems: [Int] = []
Find UITableViewDataSource
method below
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
cell.tmpValue.text = data[indexPath.row]
if selectedItems.contains(indexPath.row) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
return cell
}
Find UITableViewDelegate
Method below.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if selectedItems.contains(indexPath.row) {
let index = selectedItems.index(of: indexPath.row)
selectedItems.remove(at: index!)
} else {
selectedItems.append(indexPath.row)
}
tableView.reloadRows(at: [indexPath], with: .none)
}
Code will be changed depending on your requirement and custom cell. Hope you can do it your way. Thank you.
UPDATE
You can even use Set
also like this way,
var setSelectedItems: Set<Int> = []
UITableViewDataSource
method,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
cell.tmpValue.text = data[indexPath.row]
if setSelectedItems.contains(indexPath.row) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
return cell
}
UITableViewDelegate
method,
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if setSelectedItems.contains(indexPath.row) {
setSelectedItems.remove(indexPath.row)
} else {
setSelectedItems.insert(indexPath.row)
}
tableView.reloadRows(at: [indexPath], with: .none)
}
Upvotes: 3
Reputation: 705
Just a minor change
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MesTalentsChoixCell
cell.verb!.text = arrayVerbCount[indexPath.row].verb
if cell.isSelected
{
cell.accessoryType = UITableViewCellAccessoryType.checkmark
}
else
{
cell.accessoryType = UITableViewCellAccessoryType.none
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let cell = tableView.cellForRow(at: indexPath)
//toggle the state
cell!.isSelected = !cell!.isSelected
if cell!.isSelected
{
cell!.accessoryType = UITableViewCellAccessoryType.checkmark
}
else
{
cell!.accessoryType = UITableViewCellAccessoryType.none
}
}
Note: you should also create method for common code :-)
Upvotes: 0
Reputation: 20804
For multiple selection you should track selected cells in a Dictionary
for convenience faster access to selected and unselected indexPaths allowing you use multiple sections because the key value of our Dictionary is a string formed by (IndexPath.section)+(IndexPath.row) which is always unique combination
var selectedIndexPaths : [String:Bool] = [:]
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let currentIndexPathStr = "\(indexPath.section)\(indexPath.row)"
if(self.selectedIndexPaths[currentIndexPathStr] == nil || !self.selectedIndexPaths[currentIndexPathStr]!) {
self.selectedIndexPaths[currentIndexPathStr] = true
}else{
self.selectedIndexPaths[currentIndexPathStr] = false
}
self.tableView.reloadRows(at: [indexPath], with: .automatic)
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "npCell", for: indexPath) as! NewPlaylistTableViewCell
cell.mTitle.text = musics[indexPath.row]["title"] as! String?
cell.mArtist.text = musics[indexPath.row]["artist"] as! String?
cell.accessoryType = .checkmark
let currentIndexPathStr = "\(indexPath.section)\(indexPath.row)"
if(self.selectedIndexPaths[currentIndexPathStr] == nil || !self.selectedIndexPaths[currentIndexPathStr]!) {
cell.accessoryType = .none
}
return cell
}
Results
Upvotes: 0