Key Events and the Responder Chain: Sample Code using arrow keys in custom NSTextField
My latest adventure left me using a NSStepper to increment and decrement a NSTextField, just making the numbers go up or down by one. I set the minValue to 1 and bound the maxValue to an array controller I have, with the appropriate data. All of this works fine, including the -valueWraps behavior to always keep the value in the correct range. However, I would like to have keyboard events do the same thing as the mouse events, so I rigged up a simple custom NSTextField that intercepts keyUp: events and conforms to the -valueWraps behavior set in the NSStepper itself.
Read on to see some snippets of code with an explanation and download a sample project.
NSString *theArrow = [theEvent charactersIgnoringModifiers];
In this first bit, we are filtering out only keys pressed that are part of the numeric keypad.
Arrow keys fall into this category. The string is a string of keys pressed.
return; // reject dead keys
}if ( [theArrow length] == 1 ) {
unichar keyChar = [theArrow characterAtIndex:0];
Now we have a char that represents the key pressed, an arrow key still
if ( [[self stringValue] doubleValue] < [stepper maxValue] ) {
NSNumber *value = [NSNumber numberWithInt:[[self stringValue] intValue] + 1];
[self setStringValue:[value stringValue]];
} else if ( [[self stringValue] doubleValue] >= [stepper maxValue] ) {
[self setStringValue:@">
}
}
The above deals with the user hitting the up arrow key and the below deals with user hitting the down arrow key
if ( [[self stringValue] doubleValue] > 1 ) {
NSNumber *value = [NSNumber numberWithInt:[[self stringValue] intValue] – 1];
[self setStringValue:[value stringValue]];
} else if ( [[self stringValue] doubleValue] <= 1 )
[self setStringValue:[NSString stringWithFormat:@”>
}
Essentially, I set a NSTextField’s custom class to my StepperTextField. Then I set the outlet from the text field to a NSStepper I already have configured in the interface, correct with maxValue and minValue set for the NSStepper in IB. Of note, I use the keyUp: method because the keyDown: method is being captured by the field editor inside the NSTextField, so I never catch those events. This seemed like the simplest approach to me. Now when the user hits a down arrow, the number will decrement by one. An up arrow increments it by one. If the value will be over the maxValue, it gets set to 1. If it will be less than 1, it gets set to the maxValue.














Submitting Your Comment, give me a second...
Thanks for the sample code..