Re: Use other key than "tab" to cycle through text fields
Re: Use other key than "tab" to cycle through text fields
- Subject: Re: Use other key than "tab" to cycle through text fields
- From: Nathan Kinsinger <email@hidden>
- Date: Sat, 27 Sep 2008 05:18:35 -0600
On Sep 26, 2008, at 10:16 AM, Gerd Knops wrote:
On Sep 25, 2008, at 10:37 PM, Ken Thomases wrote:
On Sep 25, 2008, at 9:18 PM, Graham Cox wrote:
On 26 Sep 2008, at 10:24 am, Gerd Knops wrote:
I would like to use a key other than "tab" to advance to the next
text field, so that users can use a numeric keypad to enter
something like "11-22-33" and have 11, 22 and 33 end up in
different text fields.
I'd suggest not using a different key from 'Tab', since that's
very much hardwired into every Mac user.
Alternative, why not just detect when the field has the required
number of characters and move to the next field automatically? For
numeric entry this is much more user-friendly.
For implementing such a thing, see -[NSWindow selectNextKeyView:].
I know how to do that part. The tricky part is intercepting and
filtering the '-' key. given field editors etc.
One approach I tried was to implement -validateValue:forKey:error:
and intercept the key values of the fields I am interested in,
testing for a '-' as last character, removing it and advancing to
the next key field. That works (after setting the involved bindings
to 'Continuously updates value' and 'Verify immediately'), but for
some odd reason when the '-' character is entered that method is
called twice, causing it to skip a field. I hoped to avoid having to
also add connections for the individual views so that I can find the
next key view for the key field in question, but it seems to be the
least bothersome approach at that point.
Thanks
Gerd
I played around and found "a" solution. However I'm not sure if this
would be considered an abuse of the formatter/validation
architecture :-)
1) Write a custom subclass of NSNumberFormatter and implement
isPartialStringValid:proposedSelectedRange:originalString:originalSelectedRange:errorDescription
:. In it test for the '-' and set the errorDescription to some custom
string and return NO. (you could also subclass NSFormatter but you
will need to implement three more methods http://developer.apple.com/documentation/Cocoa/Conceptual/DataFormatting/Articles/CreatingACustomFormatter.html
)
2) In your controller:
a) Implement control:didFailToValidatePartialString:errorDescription:
and test the errorDescription against your custom string. If it
matches, call selectKeyViewFollowingView: on your window with the
passed in control.
b) Implement control:didFailToFormatString:errorDescription: and if
you have an empty string set the control to 0
3) In IB (in any order):
a) Add the NSNumberFormatter to your text fields then change the
class to your custom class.
b) Set your controller as the delegate of the text fields.
c) Set the nextKeyView for each of the text fields.
d) Bind the values to your model.
e) You don't need Validates Immediately or Continuous.
//
// NumberTabForwardFormatter.h
//
#import <Cocoa/Cocoa.h>
@interface NumberTabForwardFormatter : NSNumberFormatter {
}
@end
//
// NumberTabForwardFormatter.m
//
#import "NumberTabForwardFormatter.h"
@implementation NumberTabForwardFormatter
- (BOOL)isPartialStringValid:(NSString **)partialStringPtr
proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
originalString:(NSString *)origString originalSelectedRange:
(NSRange)origSelRange errorDescription:(NSString **)error
{
// the user has just deleted the last number and we have an empty
string
if (proposedSelRangePtr->location == 0)
return YES;
// the user can type '-' anywhere in the string, not just at the end
if ([[*partialStringPtr
substringWithRange:NSMakeRange(proposedSelRangePtr->location - 1, 1)]
isEqualToString:@"-"]) {
*error = @"Number Tab Forward Formatter Event";
return NO;
}
// I added this to only allow numbers, you may not need/want it, for
example you may want to allow '.' and ','
if (![[NSCharacterSet decimalDigitCharacterSet] characterIsMember:
[*partialStringPtr characterAtIndex:proposedSelRangePtr->location -
1]]) {
*error = nil;
return NO;
}
return YES;
}
@end
//
// AppController.h
//
@interface AppController : NSObject {
IBOutlet NSWindow *window;
int num1, num2, num3;
}
@property (assign) int num1, num2, num3;
@end
//
// AppController.m
//
#import "AppController.h"
@implementation AppController
@synthesize num1, num2, num3;
- (void)control:(NSControl *)control didFailToValidatePartialString:
(NSString *)string errorDescription:(NSString *)error
{
if ([error isEqualToString:@"Number Tab Forward Formatter Event"])
[window selectKeyViewFollowingView:control];
}
- (BOOL)control:(NSControl *)control didFailToFormatString:(NSString
*)string errorDescription:(NSString *)error
{
if ([string isEqualToString:@""]) {
[control setIntValue:0];
return YES;
}
NSBeep();
return NO;
}
@end
Hope that helps,
--Nathan
_______________________________________________
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