Change tintColor for selected state in UITableViewCell

73 Views Asked by At

I have a UITableViewCell which has a custom icon for the accessoryView, set as follows:

    let customDetailDisclosureButton = UIButton.init(type: .detailDisclosure)
    customDetailDisclosureButton.setImage(UIImage(named: "custom")?.withRenderingMode(.alwaysTemplate), for: .normal)
    cell.accessoryView = customDetailDisclosureButton

However, when the cell is selected, the custom icon is hidden:

TableCell with hidden accessoryView

I've tried to change the tint color of the accessoryView to white when the cell is selected, but its not changing (see above). Here's what I've tried to do.

func tableView(_: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    
    print("Will select row at: \(indexPath)")
    let selectedCell = tableView.cellForRow(at: indexPath)
    selectedCell?.textLabel?.textColor = .white
    
    if let accessoryButton = selectedCell?.accessoryView as? UIButton {
            
        // !! Doesn't change the tint color !!
        accessoryButton.tintColor = .white
    }

    guard let selectedIndexPath = self.tableView.indexPathForSelectedRow else {
        print("No existing selected row at: \(indexPath)")
        return indexPath
    }
    
    
    // The same cell has been selected twice
    if selectedIndexPath == indexPath {
        print("Same cell selected twice: \(indexPath)")
        return indexPath
    }
        
    print("Resetting to default \(selectedIndexPath)")
    // Reset to default
    let previousSelectedCell = tableView.cellForRow(at: selectedIndexPath)
    previousSelectedCell?.textLabel?.textColor = .black
    previousSelectedCell?.accessoryView?.tintColor = .systemBlue
    
    return indexPath
}
1

There are 1 best solutions below

0
HangarRash On

The easiest solution is to setup a UIImageView with two images. One for the normal state and one for the highlighted state. Tint the two images with the appropriate colors as desired.

let image = UIImage(named: "custom")?.withTintColor(.label, renderingMode: .alwaysOriginal)
let highlighted = UIImage(named: "custom")?.withTintColor(.systemBackground, renderingMode: .alwaysOriginal)
let customAccessoryView = UIImageView(image: image, highlightedImage: highlighted)
cell.accessoryView = customAccessoryView

That's all you need. Now you can remove all other code related to trying to change the accessory view's tintColor. When a row is selected the highlighted image will automatically be applied and when a row is not selected the normal image will automatically be applied.