I have a custom NSTableView
subclass filled with several custom NSTextFieldCell
subclasses. I would like to be able to change the edited cell by using the arrow keys.
I am able to accomplish this by creating a custom field editor (by subclassing NSTextView
) and returning it from the window delegate like so:
- (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 moveUp:
, moveDown:
, moveLeft:
, and moveRight:
methods to implement my desired functionality, and that all works fine. The only problem is that the field editor no longer behaves like a text field cell editor. For example, when I hit the Enter key, it inserts a newline into the text field instead of ending the editing.
How do I create a custom field editor that responds exactly like the default one does for an NSTextFieldCell
(except for those four functions that I will override)? Or is there a better way to change the functionality ofmoveUp:
, moveDown:
, moveLeft:
, and moveRight:
?
EDIT: It appears that the field editor sets the text field as its delegate when it is selected for editing. In that case, it might be helpful to just attach to the control:textView:doCommandBySelector:
delegate method as described here, but when I implement that function in either my NSTextFieldCell
subclass or my NSTableView
subclass, it never gets called. Why not?
The answer to the more general title of this question can be found in this answer: https://stackoverflow.com/a/8865953/43615
Basically, one subclasses
NSTextFieldCell
and overridesfieldEditorForView:
, where one simply creates a custom subclass ofNSTextView
and sets itsfieldEditor
property toYES
.These should be overridden in
keyDown:(NSEvent *)event
method of your subclassedNSTextFieldCell
object. You check the pressed key (one of the arrows) and otherwise call up tosuper
.I spent almost all day on this problem, but I finally figured it out. In order to be able to traverse my NSTableView subclass with the arrow keys, I had to add the following method to my NSTableView:
This is because the default field editor is an NSTextView (not an NSControl) so I needed to use the
<NSTextViewDelegate>
protocol. The view that is set as its delegate is the NSTableView, not the NSTextFieldCell. ThemoveSelectionTo...
functions are custom functions defined in my NSTableView subclass that keep track of the currently edited cell and then move it around accordingly.The easiest way to accomplish what you need is to implement
control:textView:doCommandBySelector:
in the table view's delegate.See also my answer to a similar question here: Arrow keys with NSTableView
Possibly related entry in Apple documentation:
setFieldEditor:
Controls whether the text views sharing the receiver’s layout manager behave as field editors.
Parameters
flag:
YES
to cause the text views sharing the receiver's layout manager to behave as field editors,NO
otherwise.Discussion
Field editors interpret Tab, Shift-Tab, and Return (Enter) as cues to end editing and possibly to change the first responder. Non-field editors instead accept these characters as text input. See “Text Fields, Text Views, and the Field Editor” for more information on field editors. By default, text views don’t behave as field editors.