appkitnstextfieldnstextfieldcellnsviewrepresentable

Change NSTextField text color when in edit mode


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


Solution

  • 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