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?

Accepted Reply

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

Replies

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

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.