0

I have a NSTextField which has the background colour set as clear.

When I press enter, the textfield goes into editing mode and starts renaming the file just as Xcode.

Here I want to change the background colour to white. Currently, I am changing the background colour in controlTextDidBeginEditing(_ obj: Notification) which is called after the textfield receives a change in text.

However, I am looking for a method which can change the background colour as soon as I press enter.

Here is my current code:

private class TextField: NSTextField, NSTextFieldDelegate {
    init() {
        super.init(frame: .zero)
        delegate = self
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    public func controlTextDidBeginEditing(_ obj: Notification) {
        let textField = obj.object as! NSTextField
        textField.backgroundColor = NSColor.textBackgroundColor
    }

    public func controlTextDidEndEditing(_ obj: Notification) {
        let textField = obj.object as! NSTextField
        textField.backgroundColor = NSColor.clear
    }
}

Thanks.

Rahul Katariya
  • 3,528
  • 3
  • 19
  • 24
  • Ask not what `controlTextDidBeginEditing(_:)` can do for you. Ask what you can do with `func doCommand(by aSelector: Selector!, command infoDictionary: [AnyHashable : Any]!)`. – El Tomato Dec 28 '20 at 11:57
  • Thanks El, I tried this method and found it is called when the textfield ends editing (by pressing the return key second time). – Rahul Katariya Dec 28 '20 at 12:50
  • I am afraid I don't understand what you have said. I only understand grammatically-correct English sentences. – El Tomato Dec 28 '20 at 12:57
  • No worries, thanks :). – Rahul Katariya Dec 28 '20 at 13:30
  • Not related to the issue but instead of making the text field its own delegate you could override `textDidBeginEditing(_:)` and `textDidEndEditing(_:)`. – Willeke Dec 29 '20 at 10:49
  • Is the text field editable/selectable or do you make it editable when the Return key is pressed? – Willeke Dec 29 '20 at 10:54

2 Answers2

0

If I understand correctly you want to change the color when the text become the firstResponder (i.e when a user clicks on the textField)? If so I think you should use the textShouldBeginEditing - func textShouldBeginEditing(_ textObject: NSText) -> Bool and the appropriate func control(_ control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool functions.

If I miss understand and what you actually meant is to change the background color after the user clicks the "enter" button in the keyboard that pops - you want to change the color after the textField finishes to be the firstResponder. In this case you should use the textShouldEndEditing or textDidEndEditing delegate methods and their corresponding control methods textShouldEndEditing textDidEndEditing

CloudBalancing
  • 1,461
  • 2
  • 11
  • 22
  • Unfortunately, `textShouldBeginEditing` and `control(_ control: NSControl, textShouldBeginEditing fieldEditor: NSText)` are also called after receiving text input. – Rahul Katariya Dec 28 '20 at 12:25
  • By pressing enter, I meant the textfield goes into editing mode and starts renaming the file just as Xcode. If I press enter again, it will exit the editing mode. – Rahul Katariya Dec 28 '20 at 12:28
  • Interesting, you are right - I was not aware of this behaviour on macOS... Maybe this could help - https://stackoverflow.com/questions/55078226/first-responder-on-mouse-down-behavior-nscontrol-and-nsview. Unless using @El Tomato suggestion I think you will have to create a new subclass of NSTextField and use the mouse function of NSResponder to achieve what you want... or maybe use a extension? https://developer.apple.com/documentation/appkit/nsresponder – CloudBalancing Dec 28 '20 at 12:35
  • Thanks anyway, appreciate your time. `doCommand` is also called when editing ends. – Rahul Katariya Dec 28 '20 at 12:49
0

It looks like the method to override was selectText(_ sender: Any?) which is called immediately when the NSTextField becomesFirstResponder as the text gets selected by default.

override func selectText(_ sender: Any?) {
    let textField = sender as! NSTextField
    textField.backgroundColor = NSColor.textBackgroundColor
    super.selectText(sender)
}

public func controlTextDidEndEditing(_ obj: Notification) {
    let textField = obj.object as! NSTextField
    textField.backgroundColor = NSColor.clear
}

Rahul Katariya
  • 3,528
  • 3
  • 19
  • 24