开发者

What is Best Way to Input Decimal Numbers with iPhone SDK?

开发者 https://www.devze.com 2022-12-14 12:44 出处:网络
So after finally learning how to store user input into a variable开发者_JAVA技巧, I am realizing it is rather difficult to have the user input numbers with decimals. The Number KeyPad doesn\'t allow a

So after finally learning how to store user input into a variable开发者_JAVA技巧, I am realizing it is rather difficult to have the user input numbers with decimals. The Number KeyPad doesn't allow a decimal part, and if I use Numbers & Punctuation it looks a bit weird.

So do I have to use a number Picker to smoothly allow users to input numbers? OR should I just use the Numbers & Punctuation since I was able to learn how to store that input (almost)?

Any help would be greatly appreciated.


You could always follow the same philosophy used for a Done button on the number keypad. Basically, you make your own decimal point button in that empty space in the lower-left.

Just follow the directions for adding and monitoring the button. The only thing you would need to change would be @selector(doneButton:) to @selector(decimalButton:). Your method for the decimal button would be:

- (void)decimalButton: (id) sender {
     myTextField.text = [myTextField.text stringByAppendingString:@"."];
}


For my app I rolled my own number keypad. Created a modal view with all the buttons I needed, and when my UITextfield subclass becomes first responder I animate it in.

Quite a bit of work, but you can also customise the look & feel (with your own nice buttons etc) which is what I wanted for my app.

Update: My DecimalKeyboardViewController:

I actually use a subclass of UIControl instead of a UITextfield because I display it in some custom way. If I was to subclass UITextfield I'd do something like this:

@interface DecimalNumberTextfield : UITextfield {
    NSDecimalNumber *value;
}
@property (nonatomic, retain) NSDecimalNumber *value
@end

@implementation DecimalNumberTextfield
- (BOOL)becomeFirstResponder
{
    if ([super becomeFirstResponder]) {
        [[DecimalKeyboardViewController sharedDecimalKeyboardViewController] showForField:self];
        return YES;
    } else {
        return NO;
    }
}
- (BOOL)resignFirstResponder
{
    if ([super resignFirstResponder]) {
        [[DecimalKeyboardViewController sharedDecimalKeyboardViewController] hide];
        return YES; 
    } else {
        return NO;
    }
}
- (void)setValue:(NSDecimalNumber *)aValue {
    // you need to set value and update the displayed text here
}
@end

Here is the DecimalKeyboardViewController. You'll need to create the nib file and add tags to the buttons (0-9 for the numbers probably, and other tags for the other buttons that you'd use), then hook up the buttons to -buttonPressed::

@interface DecimalKeyboardViewController : UIViewController {
    DecimalNumberTextField *fieldBeingEdited;
}
@property (nonatomic, retain) DecimalNumberTextField *fieldBeingEdited;

+ (id)sharedDecimalKeyboardViewController;
- (void)showForField:(DecimalNumberTextField *)aTextField;
- (void)hide;
- (IBAction)buttonPressed:(id)sender;
@end

@implementation DecimalKeyboardViewController
static DecimalKeyboardViewController *sharedViewController;

+ (id)sharedDecimalKeyboardViewController
{
    if (!sharedViewController) {
        sharedViewController = [[DecimalKeyboardViewController alloc]
                                initWithNibName:@"DecimalKeyboardViewController"
                                         bundle:[NSBundle mainBundle]];
    }
    return sharedViewController;
}
- (void)showForField:(DecimalNumberTextField *)aTextField
{
    self.fieldBeingEdited = aTextField;

    // add ourselves to the window unless we're there already
    UIWindow *theWindow = self.fieldBeingEdited.window;
    CGRect frame = self.view.frame;

    if (!self.view.superview) { // add ourselves to the UIWindow unless we're already visible
        frame.origin.y = theWindow.frame.size.height; // we start just out of sight at the bottom
        self.view.frame = frame;
        [theWindow addSubview:self.view];
    }

    // start animating
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

    // animate the keyboard in
    frame.origin.y = theWindow.frame.size.height - frame.size.height;
    self.view.frame = frame;

    // GO!
    [UIView commitAnimations];
}
- (void)hide
{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

    if (self.view.superview) {
        CGRect frame = self.view.frame;
        frame.origin.y = self.view.superview.frame.size.height;
        self.view.frame = frame;
    }

    [UIView commitAnimations];

    self.fieldBeingEdited = nil;    
}
- (IBAction)buttonPressed:(id)sender
{
    UIButton *button = (UIButton *)sender;

    NSDecimalNumber *oldNumber = self.fieldBeingEdited.value;
    NSDecimalNumber *newNumber;

    switch (button.tag) {
        // calculate the new number based on what button the user pressed
    }

    // update the DecimalNumbertextfield
    self.fieldBeingEdited.value = newNumber;
}
@end

Update 2: Since I subclassed UIControl I didn't have to deal with the standard keyboard popping up. If you subclass UITextfield I'd think the normal keyboard would be displayed as well. You'd have to prevent that somehow (not sure how) or subclass UIControl like I did.


If you don't want to go with Chris's answer, you could use numbers and punctuation keypad, and then "disable" all non digit/decimal point inputs by implementing the methods of UITextFieldDelegate


In the SDK 3.0 release notes, Apple wrote the following warning:

Don't draw custom buttons on top of existing keyboards. Any number of drawing, event, or compatibility problems could come up.

Now it's true, they have been accepting applications that add a button over an existing keyboard, however this technique uses an undocumented link to the UIKeyboard View and could easily be rejected the next time it's submitted. Technically it falls into the undocumented API realm, however I don't believe their automated tools pick it up so it's not being flagged.

You should post a bug on the Apple Developer Connection website, since they are counting the number of bug reports on this issue before they will address it formally...

There are an number of ways they could fix this, including:

1) Support more predefined keyboard options (decimal, currency, etc). 2) Expose the UIKeyboard methods 3) Provide customizing keyboard options that can be localized

If you intend to localize your App, you will have problems with different keypad sizes when you overlay a "." key on the empty space on one of the existing keypad (same problem that the "Done" button has in that approach).

I am currently using the overlayed "." in one of my own Apps, and will probably end up creating an entirely custom "decimal" keypad to replace this so I don't risk being rejected in an App update in the future.

-t

0

精彩评论

暂无评论...
验证码 换一张
取 消