currentEditor

I have a windowController with a NSTableView and a textfield which I use to search data in my tableView


In the controller, I intercept the keydown event and if it is a character, I want to fill the textfield with this character and give the focus to the textfield


So I write


@objc override func myKeyDown(with event: NSEvent) -> Bool {
     if ctrlRch != nil {
          window?.makeFirstResponder(ctrlRch)
          Swift.print("firstResponder is \(window?.firstResponder)")
          ctrlRch.stringValue = event.characters!
          var fieldEditor = ctrlRch.currentEditor()
          fieldEditor?.selectedRange = NSMakeRange(ctrlRch!.stringValue.count-1, 1)
          return true
}


But the caret (or the cursor) is not positionned in the textfield

What I missed?

Several questions before starting to investigate.


What is the original myKeyDown that you override ?

Do you get a print logged when you type a char ?


What is ctrlRch ? a textField I guess?

I read from doc on currentEditor() :

currentEditor() -> NSText?

When the receiver is a control displaying editable text (for example, a text field) and it is the first responder, it has a field editor, which is returned by this method. The field editor is a single

NSTextView
object that is shared among all the controls in a window for light text-editing needs


- Which is firstResponder when you type ?

- Are you sure it is the textField (ctrlRch) ?

- Where do you set focus to the textField ?

- If I understand well, fieldEditor is a NSText. Could you check the type ?

- I do not see that setting the range of this shared textView set the cursor visible in the destination textField.

- You use selectedRange on NSText. Why noy set selectedRange on the textField ?

1. What is the original myKeyDown that you override ?

The NSWindowConroller is a subclass of a baseClass, but the super.myKeyDow is never called. So the override keyword has no importance

The myKeyDow is called by the following mechanism:

_eventMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) {

            if self.myKeyDown(with: $0) {

                return nil

            } else {

                return $0

            }

        }


2 What is ctrlRch ? a textField I guess? What is the currentDitor doing ?

ctrlRch is a subclass of NSTextField and I just want it to get the focus when the user tap a key on his keyboard.

the current editor, as referred to the apple dcumentation returns the field editor for the currentControl or nil if the receiver does not have a field editor.

In my case, I always get nil for fieldEditor in

var fieldEditor = ctrlRch.currentEditor()


3. Where do you set focus to the textField ?

I'm not sure but I think that the following code put the focus on ctrlRch:

window?.makeFirstResponder(ctrlRch)


In fact, if in my subclassed ctrlRchI write the function becomeFirstResponder and resigneFirstResponder, I can see that when I call makeFirstResponder in my controller, becomeFirstResponder is called and immediatly resigneFirstResponder is called


4. Do you get a print logged when you type a char ?

I'm not sure waht you mean, but if I write

Swift.print(event.description)

I have a log of each key pressed

after the preceding answer, I saw that you added questions


Are you sure it is the textField (ctrlRch) ?

After the window?.makefirstRespnder(ctrlRch), if i write Swift.print("firstResponder is \(window?.firstResponder)") I have the following in the debugging console: firstResponder is Optional(<ivrit2.cTextField: 0x1020172f0>)


If I understand well, fieldEditor is a NSText. Could you check the type ?

No, I can't check the type of fieldEditor, because the currentEditor() function of ctrlRch always return nil


You use selectedRange on NSText. Why not set selectedRange on the textField ?

If I write ctrlRch.selectedRange I hve the following error: Value of type 'NSTextField' has no member 'selectedRange'

if currentEditor() function of ctrlRch always return ni, then selectedRange cannot be set here:

          var fieldEditor = ctrlRch.currentEditor()
          fieldEditor?.selectedRange = NSMakeRange(ctrlRch!.stringValue.count-1, 1)


You use selectedRange on NSText. Why not set selectedRange on the textField ?

If I write ctrlRch.selectedRange I hve the following error: Value of type 'NSTextField' has no member 'selectedRange'


Yes, you have to use setSelectedRange.

ctrlRch.setSelectedRange = NSMakeRange(ctrlRch!.stringValue.count-1, 1)

gives:

Value of type 'NSTextField' has no member 'setSelectedRange'

Oh yes, does not exist for textField but textView.


Could you get the currentEditor of the textField itself in

var fieldEditor = ctrlRch.currentEditor()

when the instruction

var fieldEditor = ctrlRch.currentEditor()

is executed, fieldEditor is nil

Accepted Answer

All is my fault

The lesson of it is we have to think much more harder before making a post


My subclassed control, in the override function becomeFirstResponder didn't called super.becomeFirstResponder (the function of the NSTextField). As a result, currentEditor() of the control returned nil.


When calling super.becomeFirstResponder, the function currentEditor returns the desired editor.

Sorry about all this

Second lesson: when posting a question, provide more code.


Here no one could guess what the subclass was [not] doing.


Have a good day and take care of you.

currentEditor
 
 
Q