在NSViewController的子类中管理FirstResponder

时间:2012-07-05 12:58:06

标签: objective-c macos first-responder

我有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,并阻止- (void)textViewDidChangeSelection:(NSNotification *)aNotification { [self.view.window makeFirstResponder:self]; } 响应按键。

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

NSTextView

我知道我可以将@protocol MyTextViewDelegate - (BOOL)keyPressedInTextView:(NSEvent *)theEvent; @end @interface MyTextView : NSTextView @property (assign) IBOutlet NSObject <MyTextViewDelegate> *delegate; @end 子类化为陷阱keyDown事件,但这似乎没有那么好。

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

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

@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}}

1 个答案:

答案 0 :(得分:0)

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