在NSViewController的子类中管理FirstResponder

我有 TextViewController 这是 NSViewController 的子类,它控制一个包含 NSTextView 的视图

我使用以下代码将 TextViewController 的实例附加到现有视图

TextViewController *textViewer;

...

[[self view] addSubview:[textViewer view]]; // embed new TextView in our host view
[[textViewer view] setFrame:[[self view] bounds]];  // resize the controller's view to the host size
textViewer.delegate = self;
[split.window makeFirstResponder:textViewer];

这非常有效,并且 TextViewController 捕获 keyDown 事件以执行各种操作 .

我想允许用户选择 NSTextView 中的文本来复制到剪贴板 . 不幸的是,单击 NSTextView 使其成为 FirstResponder 并停止 TextViewController 响应按键 .

我可以强制FirstResponder回到我的TextViewController,但这看起来像一个kludge .

- (void)textViewDidChangeSelection:(NSNotification *)aNotification {
    [self.view.window makeFirstResponder:self];
}

我知道我可以将 NSTextView 子类化为陷阱keyDown事件,但这似乎并没有好多少 .

我相信必须有更优雅的方式来做到这一点 .

我添加了一个NSTextView的子类,它只是将keyDown传递给控制器

@protocol MyTextViewDelegate
- (BOOL)keyPressedInTextView:(NSEvent *)theEvent;
@end

@interface MyTextView : NSTextView
@property (assign) IBOutlet NSObject <MyTextViewDelegate> *delegate;
@end

...

@implementation MyTextView
@synthesize delegate;
- (void)keyDown:(NSEvent *)theEvent {
    if([self.delegate respondsToSelector:@selector(keyPressedInTextView:)]) {
        if([self.delegate keyPressedInTextView:theEvent])
            return;
        }
    [super keyDown:theEvent];
}
@end

回答(1)

2 years ago

子类化 NSTextView 听起来像是您描述的问题的最佳解决方案 . 您希望文本视图的行为与正常情况相同,选择,复制,Cmd-A等,除了它还响应您定义的特殊按键 . 这是子类的标准用法 . 试图通过与第一响应者一起玩游戏来让视图控制器处理事情会在你发现的各种边缘情况下给你带来问题 .