UITableViewCell Selected Background Color on Multiple Selection

亡梦爱人 提交于 2019-11-28 05:16:29
Somoy Das Gupta

Swift 4.2

For multiple selections you need to set the UITableView property allowsMultipleSelection to true.

myTableView.allowsMultipleSelection = true

In case you subclassed the UITableViewCell, you override setSelected(_ selected: Bool, animated: Bool) method in your custom cell class.

 override func setSelected(_ selected: Bool, animated: Bool) {
     super.setSelected(selected, animated: animated)

     if selected {
         contentView.backgroundColor = UIColor.green
     } else {
         contentView.backgroundColor = UIColor.blue
     }
 }
OverD

All the above answers are fine but a bit to complex to my liking. The simplest way to do it is to put some code in the cellForRowAtIndexPath. That way you never have to worry about changing the color when the cell is deselected.

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

    /* this is where the magic happens, create a UIView and set its
       backgroundColor to what ever color you like then set the cell's
       selectedBackgroundView to your created View */

    let backgroundView = UIView()
    backgroundView.backgroundColor = YOUR_COLOR_HERE
    cell.selectedBackgroundView = backgroundView
    return cell
}

This worked for me:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
    selectedCell.contentView.backgroundColor = UIColor.redColor()
}

// if tableView is set in attribute inspector with selection to multiple Selection it should work.

// Just set it back in deselect 

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    var cellToDeSelect:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
    cellToDeSelect.contentView.backgroundColor = colorForCellUnselected
}


//colorForCellUnselected is just a var in my class
Ahmed Lotfy

Swift 3

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier", for: indexPath)
    cell.selectionStyle = .none
    return cell
}

Swift 2

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier", for: indexPath)
     cell.selectionStyle = .None
     return cell
}
superarts.org

The problem with Kersnowski's approach is that when the cell is redrawn the changes made when it's selected/deselected will be gone. So I would move the changes into the cell itself, which means subclassing is required here. For example:

class ICComplaintCategoryCell: UITableViewCell {
    @IBOutlet var label_title: UILabel!
    @IBOutlet var label_checkmark: UILabel!

    override func layoutSubviews() {
        super.layoutSubviews()
        reload()
    }
    func reload() {
        if isSelected {
            contentView.backgroundColor = UIColor.red
        }
        else if isHighlighted{
            contentView.backgroundColor = UIColor.red
        }
        else {
            contentView.backgroundColor = UIColor.white
        }
    }
}

And in your table view delegate just call reload:

if let cell = self.table.cellForRowAtIndexPath(path) as? ICComplaintCategoryCell {
    cell.reload()
}

Updated for Swift 3+, thanks @Bogy

You can also set cell's selectionStyle to.none in interface builder. The same solution as @AhmedLotfy provided, only from IB.

Swift 3

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath)!
     selectedCell.contentView.backgroundColor = UIColor.darkGray
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
     let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath)!
     selectedCell.contentView.backgroundColor = UIColor.clear
}

For Swift 4, you can do this in two ways

1) class: UITableViewCell

override func awakeFromNib() {
    super.awakeFromNib()
    //Costumize cell

    selectionStyle = .none
}

or

2) tableView cellForRowAt

    cell.selectionStyle = .none

UITableViewCell has an attribute multipleSelectionBackgroundView. https://developer.apple.com/documentation/uikit/uitableviewcell/1623226-selectedbackgroundview

Just create an UIView define the .backgroundColor of your choice and assign it to your cells .multipleSelectionBackgroundView attribute.

By adding a custom view with the background color of your own you can have a custom selection style in table view.

let customBGColorView = UIView()
customBGColorView.backgroundColor = UIColor(hexString: "#FFF900")
cellObj.selectedBackgroundView = customBGColorView

Add this 3 line code in cellForRowAt method of TableView. I have used an extension in UIColor to add color with hexcode. Put this extension code at the end of any Class(Outside the class's body).

extension UIColor {    
convenience init(hexString: String) {
    let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
    var int = UInt32()
    Scanner(string: hex).scanHexInt32(&int)
    let a, r, g, b: UInt32
    switch hex.characters.count {
    case 3: // RGB (12-bit)
        (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
    case 6: // RGB (24-bit)
        (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
    case 8: // ARGB (32-bit)
        (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
    default:
        (a, r, g, b) = (255, 0, 0, 0)
    }
    self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255)
  }
}

SWIFT 3/4

Solution for CustomCell.selectionStyle = .none if you set some else style you saw "mixed" background color with gray or blue.

And don't forget! func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) didn't call when CustomCell.selectionStyle = .none.

extension MenuView: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cellType = menuItems[indexPath.row]
        let selectedCell = tableView.cellForRow(at: indexPath)!
            selectedCell.contentView.backgroundColor = cellType == .none ? .clear : AppDelegate.statusbar?.backgroundColor?.withAlphaComponent(0.15)

        menuItemDidTap?(menuItems[indexPath.row])

        UIView.animate(withDuration: 0.15) {
            selectedCell.contentView.backgroundColor = .clear
        }
    }
}

Swift 4

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
{
    let selectedCell = tableView.cellForRow(at: indexPath)! as! LeftMenuCell
    selectedCell.contentView.backgroundColor = UIColor.blue
}

If you want to unselect the previous cell, also you can use the different logic for this

var tempcheck = 9999
var lastrow = IndexPath()
var lastcolor = UIColor()
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
    if tempcheck == 9999
    {
        tempcheck = 0
        let selectedCell = tableView.cellForRow(at: indexPath)! as! HealthTipsCell
        lastcolor = selectedCell.contentView.backgroundColor!
        selectedCell.contentView.backgroundColor = UIColor.blue
        lastrow = indexPath
    }
    else
    {
        let selectedCelllasttime = tableView.cellForRow(at: lastrow)! as! HealthTipsCell
        selectedCelllasttime.contentView.backgroundColor = lastcolor
        let selectedCell = tableView.cellForRow(at: indexPath)! as! HealthTipsCell
        lastcolor = selectedCell.contentView.backgroundColor!
        selectedCell.contentView.backgroundColor = UIColor.blue
        lastrow = indexPath
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!