I came up with a different solution. Subclassing NSTableCellView would have been fine if Cocoa supported @IBOutletCollection. Because then I could have one Cell subclass that has an array of all NSTextFields in the cell. But since I had many kinds of cells with varying numbers of NSTextFields I didn't like this option. Instead, I took a look at Apple's documentation for the backgroundStyle
property in NSTableCellView.
The default implementation automatically forwards calls to all subviews that implement setBackgroundStyle: or are an NSControl, which have NSCell classes that respond to backgroundStyle.
If my TextFields implement setBackgroundStyle then they should get notified when the cell selection changes. However, this forwarding of the background style is not recursive. Because my NSTextFields were within NSStackViews they were not getting the message. To get around this, I just wrote an extension to implement setBackgroundStyle on all NSViews. It just forwards the message on. Lastly, I added an extension to NSTextField to also implement this method. From this extension, I change the text color and call super. This solution is also nice because no subclasses are needed. No subclasses of NSTableCellView or of NSTextField.
Adding this functionality to all views and to all NSTextFields could cause issues with NSTextFields that are not within NSTableViews changing color unexpectedly. But so far, only the ones within my TableViews/OutlineViews are changing color and thats exactly what I was looking for. If you see textfields changing color that you don't expect, you may want to subclass NSTextField and implement a setBackgroundStyle override only on that subclass instead of adding it to all NSTextFields.
The code in Swift 3 I used is pasted below.
extension NSView {
func setBackgroundStyle(_ newValue: NSBackgroundStyle) {
for view in self.subviews {
view.setBackgroundStyle(newValue)
}
}
}
extension NSTextField {
override func setBackgroundStyle(_ newValue: NSBackgroundStyle) {
switch newValue {
case .dark:
self.textColor = NSColor.controlLightHighlightColor
case .light, .lowered, .raised:
self.textColor = NSColor.labelColor
}
super.setBackgroundStyle(newValue)
}
}
- (void)tableViewSelectionIsChanging:(NSNotification *)aNotification
for this to work during mouse selection. Is this the delay you've been referring to? – pointum