Re: Changing up/down arrow behavior for NSTextField
Re: Changing up/down arrow behavior for NSTextField
- Subject: Re: Changing up/down arrow behavior for NSTextField
- From: Duncan Champney <email@hidden>
- Date: Thu, 14 Feb 2008 09:44:48 -0500
As mentioned in a previous post, using a key binding and the
control:textView:doCommandBySelector method seems the way to do
this, but I can't find an explanation of how to do this, and am not
clear on how bindings work.
I'm not sure what you mean by a "key binding". You shouldn't have to
do anything other than implement -textView:doCommandBySelector: in the
NSTextField subclass you want to treat specially. For example:
@implementation MyTextField
-(BOOL)textView:(NSTextView *)aTextView doCommandBySelector:
(SEL)aSelector{
NSLog(@"selector: %s", (char *)aSelector);
return NO;
}
this will log the selector that gets sent every non-character key
press. Looking at the log, you can see, for example, that the up arrow
sends the "moveUp:" selector and shift+up sends
"moveUpAndModifySelection:". To make use of this, you can either
examine/compare aSelector and do everything in -
textView:doCommandBySelector: or do something like this (which I think
is more readable and has the added benefit of passing unhanded events
up the responder chain):
@implementation MyTextField
-(BOOL)textView:(NSTextView *)aTextView doCommandBySelector:
(SEL)aSelector{
return [self tryToPerform:aSelector with:aTextView];
}
-(void)moveUpAndModifySelection:(id)sender{
NSLog(@"Increment by 10");
}
-(void)moveUp:(id)sender{
NSLog(@"Increment by 1");
}
The details as to why this work go something like this:
When a text field is edited, a NSTextView called the field editor is
attached to it. The field editor's delegate is automagically set to
the text field it's editing. When a key is pressed, NSTextView's
keyDown: is called which passes the event to interpretKeyEvents:
which, in turn, sends the event to the input manager for processing.
If it's a character (a, b, c, etc.) it will come out as an -
insertText: call. If it's a non-character event (tab, enter, etc) it
will come out as a call to -doCommandBySelector:.
You don't want to override these methods directly in your field editor
because you might require different behavior for each field in your
app and the same field editor is used for all of them. But remember
that the text field that is being edited is the field editor's
delegate. So you can implement the delegate method -
textView:doCommandBySelector: in your text field and do the work there
instead.
There's a great explanation of all this by Douglas Davidson (I think?)
in the list archives. I can't find it at the moment, but it's worth
looking up.
Cheers,
-Joshua Emmons
------
Joshua,
Now I understand. There are predefined command selectors that the text
system generates for certain keystrokes, and I just need to intercept
those command selectors in my code.
Happily, the keystrokes I want to special-case, up/down arrow and
shift up/down arrow, have existing command selectors ("moveUp",
"moveDown", "moveUpAndModifySelection", and
"moveDownAndModifySelection"). I wrote my code to handle those 4
messages, and ignore others. Rather than using "-
tryToPerform:aSelector", I just do a string match on the different
command selectors, like this:
NSLog(@"Command = %s", command);
if (!strcmp((char *)command, "moveUp:"))
//handle up arrow
else if (!strcmp((char *)command, "moveUpAndModifySelection:"))
//handle shift up arrow
else if (!strcmp((char *)command, "moveDown:"))
//handle down arrow
else if (!strcmp((char *)command, "moveDownAndModifySelection:"))
//handle shift down arrow
[control setDoubleValue: [control doubleValue] + value];
[self performSelector: [control action] withObject: (id) control];
I adjust the value of my field, then invoke the IBAction for the field
directly, so it gets handled as normal.
Thanks for your help.
What if I needed to handle a keystroke for which there is not a
defined method selector? (Various keystrokes return no-op, and I might
wand shift-command-option up arrow, or somesuch.)
How would I handle those cases? Is there a way to intercept key down
events for the NSTextView when it is the first responder?
Duncan C
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden