Custom Field Editor for NSTextFieldCell in NSTableView

I have a custom subclass of NSTableView populated with several custom subclasses of NSTextFieldCell . I would like to be able to modify the edited cell using the arrow keys.

I can do this by creating my own field editor (by subclassing NSTextView ) and returning it from the window delegate as follows:

 - (id) windowWillReturnFieldEditor:(NSWindow *) aWindow toObject:(id) anObject { if ([anObject isEqual:myCustomTable]) { if (!myCustomFieldEditor) { myCustomFieldEditor = [[MyNSTextViewSubclass alloc] init]; [myCustomFieldEditor setTable:anObject]; } return myCustomFieldEditor; } else { return nil; } } 

In MyNSTextViewSubclass I override the methods moveUp: moveDown: moveLeft: and moveRight: to implement my desired functions, and everything works fine. The only problem is that the field editor no longer behaves like a text field cell editor. For example, when I press the Enter key, it inserts a new line into the text field, and does not finish editing.

How do I create a custom field editor that responds in the same way as the default for NSTextFieldCell (with the exception of the four functions that I override)? Or is there a better way to change the functionality of moveUp: moveDown: moveLeft: and moveRight: :?

EDIT: It looks like the field editor sets the text field as its delegate when it is selected for editing. In this case, it would be useful to simply attach control:textView:doCommandBySelector: to the delegate method, as described here , but when I implement this function either in my NSTextFieldCell subclass or my NSTableView subclass, it is never called. Why not?

+4
source share
5 answers

I spent almost all day on this problem, but I finally figured it out. To be able to traverse my subclass of NSTableView using the arrow keys, I had to add the following method to my NSTableView:

 - (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)aSelector { if(aSelector == @selector(moveUp:)) { [self moveSelectionToPreviousRow]; return YES; } else if(aSelector == @selector(moveDown:)) { [self moveSelectionToNextRow]; return YES; } else if(aSelector == @selector(moveLeft:)) { [self moveSelectionToPreviousColumn]; return YES; } else if(aSelector == @selector(moveRight:)) { [self moveSelectionToNextColumn]; return YES; } return NO; } 

This is because the default field editor is NSTextView (not NSControl), so I need to use the <NSTextViewDelegate> protocol. The view that is set as its delegate is an NSTableView, not an NSTextFieldCell. The moveSelectionTo... functions are user-defined functions defined in my NSTableView subclass that track the currently edited cell and then move it accordingly.

+4
source

Perhaps a related entry in the Apple documentation:

setFieldEditor:

Controls how text views share the recipient linker manager as field editors.

 - (void)setFieldEditor:(BOOL)flag 

Parameters

flag: YES to force text views to share the recipient layout manager as field editors, NO otherwise.

Discussion

Field editors interpret Tab, Shift-Tab, and Return (Enter) as replicas to complete editing and possibly to change the first responder. Instead of field editors, these characters are entered as text characters. See “Text Fields, Text Views, and the Field Editor” for more information on field editors. By default, text views do not work as a field editor.

+1
source

The easiest way to accomplish what you need is to implement control:textView:doCommandBySelector: in the table view delegate.

See also my answer to a similar question: Arrow keys with NSTableView

0
source

The answer to the more general name of this question can be found in this answer: fooobar.com/questions/1314467 / ...

Basically, one subclass of NSTextFieldCell overrides fieldEditorForView: where you simply create a custom subclass of NSTextView and set its fieldEditor property to YES .

0
source

They must be overridden in the keyDown:(NSEvent *)event method of your NSTextFieldCell subclass object. You check the pressed key (one of the arrows) and otherwise call super .

-1
source

Source: https://habr.com/ru/post/1314463/


All Articles