简体   繁体   中英

Track selection range change for NSTextField (cocoa)

Does anyone have any idea how I can track NSTextField.currentEditor.selectedRange value changes for NSTextField ?

There is this wonderful thing NSTextViewDidChangeSelectionNotification , it does exactly what I need, but it works only for NSTextView .

I've tried to play with KVC/KVO but I didn't get what I wanted. I assume I did something wrong.

I will try to explain what I need to achieve.

I have NSTextField , below I have a label where I want to put values from NSTextField.currentEditor.selectedRange of text selection above. In realtime, ie I want to update my label content continuously with selection length and start position from NSTextField.currentEditor.selectedRange while selecting area of text.

NSTextField uses the field editor of the current window to do the actual text editing, and that is an NSTextView . To subscribe to NSTextViewDidChangeSelectionNotification on that text view , you need to find out when your field gets keyboard focus and then ask it for its currentEditor .

Sadly, it seems controlTextDidBeginEditing: is never called, but you can override becomeFirstResponder to get the same effect (be sure to call super).

I can't find a good spot to unsubscribe though, as the text field only has keyboard focus for a split-second, and then loses it when it creates and activates the field editor NSTextView.

So in the end, what I'm doing is subscribing for the notification with a nil object when the view is created, unsubscribing in dealloc, and checking if notification.object == self.currentEditor in the notification handler and ignoring all others.

You could implement -windowWillReturnFieldEditor:toObject: on your NSWindow delegate and return a different field editor for the control(s) you care about, perhaps with the relevant NSTextView notifications set up just for that field editor. Or, of course, you could return your own subclass of NSTextView , though that is probably unnecessary here.

As mentioned in this "retired" article , the "field editor" designates the current text field as its delegate. Since the field editor is an NSTextView instance, we can implement any NSTextViewDelegate method in our NSTextField subclass.

- (void)textViewDidChangeSelection:(NSNotification *)notification
{
  NSRange selection = self.currentEditor.selectedRange;
  NSLog(@"selection = (location: %lu, length: %lu)", selection.location, selection.length);
}

Enjoy! ✌️

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM