user1715916 user1715916 - 1 month ago 7
iOS Question

Selecting Cells in Table Not Working Correctly

I have a static table in a TableViewController. Whenever I select a row, it fills the entire cell with a grey color. It does this for every row I tap. If I use:


cell.selectionStyle = .none


It will make the cell fill with white instead.

Tableview Attributes Inspector:

TableView Attributes Inspector

TableViewCell Attributes Inspector:

TableViewCell Attributes Inspector

TableViewController:

import UIKit

class OptionTableViewController: UITableViewController {

@IBOutlet var optionsTable: UITableView!

let defaults = UserDefaults.standard

let numberOfRows = [7,2]

let cellIdentifier = "OptionCells"

override func viewDidLoad() {
super.viewDidLoad()

optionsTable.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that con be recreated.
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 2
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
var rows = 0
if(section < numberOfRows.count){
rows = numberOfRows[section]
}
return rows
}

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.selectionStyle = .none
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)

cell.textLabel?.text = optionSelections[indexPath.row]
return cell
}
}


I believe I have everything setup correctly. Why does it fill in the cells when I tap them?

Update:
I updated the code to show what I currently have.

Update 2:
I've included a couple of pictures to show what the table looks like before and after tapping every other cell.

Update 3:
I was dequeuing cells to change the accessory type to checkmark.

Before:
Before Tapping Cells

After:
After Tapping Every Other Cell

Answer

As discussed in comments, I think the problem is a symptom of dequeuing cells in the didSelectRow(at:) method:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
}

You should instead use

    let cell = tableView.cellForRow(at: indexPath)

That gets the cell that is currently at the given indexPath (be aware that it may return nil if that indexPath has been scrolled off or was never on screen). Dequeuing gets an unused cell to go at the given indexPath - which (I think) then sits in front of the existing cell - hence the weird behaviour.

Comments