I have a TextViewController
which is a subclass of NSViewController
which controls a View containing a NSTextView
I attach an instance of TextViewController
to an existing view with the following code
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];
This works quite well, and the TextViewController
traps the keyDown
Event to perform various actions.
I wanted to allow users to select text in the NSTextView
to copy to clipboard.
Unfortunately clicking in the NSTextView
makes this the FirstResponder
and stops TextViewController
from responding to key presses.
I can force the FirstResponder back to my TextViewController, but this seems like a kludge.
- (void)textViewDidChangeSelection:(NSNotification *)aNotification {
[self.view.window makeFirstResponder:self];
}
I know I could subclass NSTextView
to trap the keyDown Event, but this doesn't seem much better.
I am sure there must be a more elegant way of doing this.
I added a subclass of NSTextView which just passes the keyDown to the controller
@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
Subclassing NSTextView
sounds like the best solution for the problem you described. You want a text view that behaves like normal to select, copy, Cmd-A, etc. except that it also responds to special key presses you've defined. This is a standard use of a subclass. Trying to have the view controller handle things by playing games with the first responder will give you problems in various edge cases like the one you discovered.