Change NSTextField text color when in edit mode

114 views Asked by At

Using NSTextField I'd like to change the text color from black to white when going into edit mode.

Right now, it:

  1. Defaults to black when not selected (GOOD)

enter image description here

  1. Defaults to white when selected (GOOD)

enter image description here

  1. Changes color to black when editing starts (NOT GOOD), would like for it to be white.

enter image description here

I know I could set the textColor property to .white but that would also set the color to white when the row is not selected (see point 1.), which I don't want. Huge thanks in advance!

Code I'm using now for reference, note is part of a NSViewRepresentable struct.

func makeNSView(context:Context) -> NSTextField{
    let osTextView = NSTextField(string: inputText)
    osTextView.maximumNumberOfLines = 1
    osTextView.isBordered = false
    osTextView.delegate = context.coordinator
    osTextView.drawsBackground = true
    osTextView.backgroundColor = .none
    //osTextView.textColor = .white
    
    return osTextView
}

I've tried adding the following and it almost gets the job done, however it only triggers when edit begins as opposed to when NSTextField becomes editable.

func control(_ control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool {
        fieldEditor.textColor = .white
        return true
    }

enter image description here

1

There are 1 answers

0
MMV On BEST ANSWER

So the way I managed to solve it is by subclassing NSTextField and overriding becomeFirstResponder. As that only triggers when the field goes into edit mode I can set there the color to white.

import AppKit

final class NSTextFieldFirstResponderAware: NSTextField{

override func becomeFirstResponder() -> Bool {
    self.textColor = .white
    return super.becomeFirstResponder()
}

}

Once the user finishes I reset the color at

func controlTextDidEndEditing(_ obj: Notification) {
        guard let textField = obj.object as? NSTextField else {
            return
        }
        
        textField.textColor = nil
}

You may wonder why I don't reset it at resignsFirstResponder, the reason is this (TLDR -> would not work).

And here is the end result:

rows changing colors as intended