That's a question for Mac app (Cocoa).
I want to change the standard highlighting.
I thought to use tableView.selectionHighlightStyle.
But there are only 2 values: .none and .regular. Cannot find how to define a custom one.
So I tried a workaround:
- set tableView.selectionHighlightStyle to .none
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
tableView.selectionHighlightStyle = .none
- keep track of previousSelection
- Then, in tableViewSelectionDidChange
-
- reset for previousSelection
func tableViewSelectionDidChange(_ notification: Notification) { }
if previousSelection >= 0 {
let cellView = theTableView.rowView(atRow: previousSelection, makeIfNecessary: false)
cellView?.layer?.backgroundColor = .clear
}
-
- set for the selection to a custom color
let cellView = theTableView.rowView(atRow: row, makeIfNecessary: false)
cellView?.layer?.backgroundColor = CGColor(red: 0, green: 0, blue: 1, alpha: 0.4)
previousSelection = row
Result is disappointing :
Even though tableView.selectionHighlightStyle is set to .none, it does overlays the cellView?.layer
Is there a way to directly change the color for selection ?
What's the issue ?
That's a method that creates and returns a cell view. It gets called frequently and not by you. It's not an appropriate place to set a tableview property that you only need to set once, when you want it set.
I change my mind to stay consistent with system behaviour and will change the color of the text (to white) when selected, to make it more readable.
What if the user's in dark mode?
I checked some code where I was doing this. What I'm doing is subclassing the row view and overriding this method:
// Customize selection.
override func drawSelection(in dirtyRect: NSRect)
{
if self.selectionHighlightStyle != .none
{
let frameColor = NSColor.selectedContentBackgroundColor
NSGraphicsContext.current?.saveGraphicsState()
frameColor.setStroke()
let rect =
CGRect(
x: box.frame.minX + 5,
y: box.frame.minY + 4,
width: box.frame.width - 10,
height: box.frame.height - 10)
let roundRect =
NSBezierPath(roundedRect: rect, xRadius: 4, yRadius: 4)
roundRect.lineWidth = 4
roundRect.stroke()
NSGraphicsContext.current?.restoreGraphicsState()
}
}