macosnstableview

NSTableView Change cell color when selected


This is a macOS question

In

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?

I'm using

 func tableViewSelectionDidChange(_ notification: Notification) {


    cell.layer?.backgroundColor = mintGreen.cgColor

to change the cell color.

Is it possible to change the color when the cell is selected?

Thanks


Solution

  • Did you ever get anywhere with this?

    Realise this is an old question now, but I couldn't find a solution to this problem documented anywhere, so this is what I've come up with:

    This code assumes an NSTableView with one column and therefore that the cell you are interested is in the zero indexed column. It also assumes a reference to the NSTableView on the delegate of 'theTableView'.

    func tableViewSelectionDidChange(_ notification: Notification) {
    
        // You'd probably want to handle this else statement more elegantly
        guard let selected = theTableView?.selectedRow else { return }
    
        if (selected != -1) {
    
            if let numberOfRows = theTableView?.numberOfRows {
    
                let sequenceOfRows = 0..<numberOfRows
    
                for row in sequenceOfRows.reversed() {
    
                    if row == selected {
    
                        if let cell = theTableView?.view(atColumn: 0, row: selected, makeIfNecessary: false) {
                            cell.layer?.backgroundColor = NSColor.green.cgColor
                        }
    
                    } else {
    
                        if let cell = theTableView?.view(atColumn: 0, row: Int(row), makeIfNecessary: false) {
                            cell.layer?.backgroundColor = NSColor.clear.cgColor
                        }
                    }
    
                }
            }
    
        } else {
    
            // No row is selected, so iterate over all and revert background to .clear
    
            if let numberOfRows = theTableView?.numberOfRows {
    
                let sequenceOfRows = 0..<numberOfRows
    
                for row in sequenceOfRows {
    
                    if let cell = theTableView?.view(atColumn: 0, row: Int(row), makeIfNecessary: false) {
                        cell.layer?.backgroundColor = NSColor.clear.cgColor
                    }
    
                }
            }
        }
    }
    

    This works, and technically answers the question, but feels really horrible, having to iterate over all the rows to assess which background colour to change, and to change all the rows back again when the row selection changes or the row is deselected. I can't help feel there must be many more elegant or efficient ways to do this, but as I say can't find any documented myself.

    Would be grateful if anyone else could update if there is another more succinct way of doing this, or if there is another pattern aside from the NSTableView delegates to achieve this.