NSTableView 中 NSTextFieldCell 的自定义字段编辑器

发布于 2024-09-08 08:17:50 字数 1423 浏览 9 评论 0原文

我有一个自定义的 NSTableView 子类,其中填充了几个自定义的 NSTextFieldCell 子类。我希望能够使用箭头键更改编辑的单元格。

我可以通过创建自定义字段编辑器(通过子类化 NSTextView)并从窗口委托返回它来实现此目的,如下所示:

- (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;
    }
}

MyNSTextViewSubclass 中,我覆盖 moveUp:moveDown:moveLeft:moveRight: 方法来实现我想要的功能,并且一切正常。唯一的问题是字段编辑器的行为不再像文本字段单元格编辑器。例如,当我按 Enter 键时,它会在文本字段中插入换行符,而不是结束编辑。

如何创建一个自定义字段编辑器,其响应与 NSTextFieldCell 的默认编辑器完全相同(除了我将覆盖的那四个函数)?或者是否有更好的如何更改 moveUp:moveDown:moveLeft:moveRight: 的功能?

编辑:当选择文本字段进行编辑时,字段编辑器似乎将文本字段设置为其委托。在这种情况下,按照 此处,但是当我在我的 中实现该功能时NSTextFieldCell 子类或我的 NSTableView 子类,它永远不会被调用。为什么不呢?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

左耳近心 2024-09-15 08:17:50

我几乎花了一整天的时间来解决这个问题,但我终于弄清楚了。为了能够使用箭头键遍历我的 NSTableView 子类,我必须将以下方法添加到我的 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;
}

这是因为默认字段编辑器是 NSTextView (不是 NSControl),所以我需要使用 协议。设置为其委托的视图是 NSTableView,不是 NSTextFieldCell。 moveSelectionTo... 函数是在我的 NSTableView 子类中定义的自定义函数,用于跟踪当前编辑的单元格,然后相应地移动它。

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:

- (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 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. The moveSelectionTo... functions are custom functions defined in my NSTableView subclass that keep track of the currently edited cell and then move it around accordingly.

筑梦 2024-09-15 08:17:50

Apple 文档中可能相关的条目:

setFieldEditor:

控制共享接收器布局管理器的文本视图是否充当字段编辑器。

- (void)setFieldEditor:(BOOL)flag

参数

flagYES使共享接收器布局管理器的文本视图充当字段编辑器,否则NO

讨论

字段编辑器将 Tab、Shift-Tab 和 Return (Enter) 解释为结束编辑并可能更改第一响应者的提示。非字段编辑器接受这些字符作为文本输入。有关字段编辑器的更多信息,请参阅“文本字段、文本视图和字段编辑器”。默认情况下,文本视图不充当字段编辑器。

Possibly related entry in Apple documentation:

setFieldEditor:

Controls whether the text views sharing the receiver’s layout manager behave as field editors.

- (void)setFieldEditor:(BOOL)flag

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.

疏忽 2024-09-15 08:17:50

这个问题的更一般标题的答案可以在这个答案中找到:https://stackoverflow.com/a/8865953/43615基本上

,一个子类 NSTextFieldCell 并覆盖 fieldEditorForView:,其中只需创建一个 NSTextView 的自定义子类并设置其 fieldEditor 属性设置为 YES

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 overrides fieldEditorForView:, where one simply creates a custom subclass of NSTextView and sets its fieldEditor property to YES.

小女人ら 2024-09-15 08:17:50

完成您所需的最简单方法是在表视图的委托中实现 control:textView:doCommandBySelector:

另请参阅我对类似问题的回答:带有 NSTableView 的箭头键

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

柳若烟 2024-09-15 08:17:50

这些应该在子类 NSTextFieldCell 对象的 keyDown:(NSEvent *)event 方法中重写。您检查按下的键(箭头之一),否则调用 super

These should be overridden in keyDown:(NSEvent *)event method of your subclassed NSTextFieldCell object. You check the pressed key (one of the arrows) and otherwise call up to super.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文