I am trying to show items in NSTableView
but one of them (the item that previously was activated by an action (its name is stored in alreadyActivatedItem
variable)) should be disabled and shown with a red text.
So far I managed to make disabling work properly.
I just cannot manage colouring the already activated item be red text. My code below will colour ALL cells' text in red.
extension PreferencesViewController: NSTableViewDelegate {
// disable selecting the already activated item
func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
return !(myArray[row].name == alreadyActivatedItem)
}
// colouring the already activated item in red (it is also disabled)
func tableView(_ tableView: NSTableView, willDisplayCell cell: Any, for tableColumn: NSTableColumn?, row: Int) {
guard let c = cell as? NSTextFieldCell else {
return
}
if c.stringValue == alreadyActivatedItem {
c.textColor = .red
}
}
}
I also tried an other way:
// colouring the already activated item in red (it is also disabled)
func tableView(_ tableView: NSTableView, willDisplayCell cell: Any, for tableColumn: NSTableColumn?, row: Int) {
guard let c = tableColumn?.dataCell(forRow: row) as? NSTextFieldCell else {
return
}
if c.stringValue == alreadyActivatedRow {
c.textColor = .red
}
}
In both cases I will have all the rows with red text:
While debugging, I can see that:
let c = cell as? NSTextFieldCell
seems to get the current row's cell, at least I get back the row's stringValue
correctly with c.stringValue
if c.stringValue == alreadyActivatedRow
seems to work good, at least it only steps inside if the condition is true.So why still do all the items get red colour?
How to achieve my goal then?
(Xcode 11.3.1, Swift 5.1.3)
Cells are reused. You have to add an else
clause to set the color always to a defined state.
if c.stringValue == alreadyActivatedItem {
c.textColor = .red
} else {
c.textColor = .black
}
Or simpler
c.textColor = c.stringValue == alreadyActivatedItem ? .red : .black
I recommend even a view based table view and Cocoa Bindings.