Search code examples
swiftuitableviewuibackgroundcolor

Issue with Swift TableViewCell: change background color for selected row


I have a strange issue with my tableView. I have a List of audio tracks and a segue to an audio player in order to play the selected track at a specific row. Everything works fine!

I wanted to change the background color for the selected row in the table so that, once the user play the audio and come back to the list of tracks (my Table View Controller) , he can see which are the previously selected rows.

But when I run It change me the color not only for the row at index path I selected but also to the item at index path + 10. If I select the First Row it change me the color for the row at the index: 0, 10, 20, 30...

In order to change the color of the selected cell I did the follow:

// MARK: - Navigation
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    self.performSegueWithIdentifier("audioPlayer", sender: tableView)

    var selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath) as CustomTableViewCell
    selectedCell.contentView.backgroundColor = UIColor.greenColor()
    selectedCell.backgroundColor = UIColor.blueColor()

Please find a screenshot of my issue, I have selected just three rows: 1, 3, 5 but I get selected 1,3,5,11,13,15,21,23 and so on... : https://www.dropbox.com/s/bhymu6q05l7tex7/problemaCelleColore.PNG?dl=0

For further details - if can help - here it is my Custom Table View class:

    import UIKit

    class CustomTableViewCell: UITableViewCell {

@IBOutlet weak var artista: UILabel!

@IBOutlet weak var brano: UILabel!

var ascoltato = false

@IBOutlet weak var labelRiproduciAscoltato: 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
}

func setCell(artista: String, brano: String){
    self.artista.text = artista
    self.brano.text = brano
}

   }  // END MY CUSTOM TABLE VIEW CELL

Here it is the method cellForRowAtIndexPath in my TableViewController:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) as CustomTableViewCell

    var tracks : Brani  //Brani is my custom Object for handle my tracks

    cell.setCell(tracks.title!, brano: tracks.author!)


    return cell

}

I am running on iPad Air with iOS 7.1.

Thank you in advance for any suggestion or advice related to my issue.


Solution

  • This is probably because UITableViewCells are recycled. This means the formerly selected tableViewCell gets reused by the cells at the lower indexes. This is expected behavior of a UITableView and makes sense, as it saves memory usage. To fix the issue, you will need to have your datasource keep a track of which cell is selected, and updated the cell's background color accordingly.

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    self.performSegueWithIdentifier("audioPlayer", sender: tableView)
    //datasource is updated with selected state
    //cell is updated with color change
    }
    

    Then in your cellForRowAtIndexPath method:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) as CustomTableViewCell
    
        var tracks : Brani  //Brani is my custom Object for handle my tracks
    
        cell.setCell(tracks.title!, brano: tracks.author!)
        //update cell style here as well (by checking the datasource for selected or not). 
    
        return cell
    }