2

So after finally learning how to store user input into a variable, 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.

Zach Smith
  • 5,490
  • 26
  • 84
  • 139
  • Here's a similar question that had some good answers: http://stackoverflow.com/questions/276382/best-way-to-enter-numeric-values-with-decimal-points – Chris Long Dec 22 '09 at 21:11
  • 1
    yeah i saw this. the OP starts with decimals then the post moves to changing the numbers into currency. i don't need currency conversion with decimals i need the ability to allow user to input 3454.43434343 for example – Zach Smith Dec 22 '09 at 21:16

4 Answers4

2

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:@"."];
}
Chris Long
  • 3,007
  • 4
  • 30
  • 37
  • TY for your reply. Wow, looks like some work involved there :) Wonder which would be easier: Making a revised keyboard or learning how to convert the UIPicker data into a variable....Will Apple allow the modification of the keypad when reviewing the app? – Zach Smith Dec 22 '09 at 21:22
  • Haha, shouldn't be too hard if you know Photoshop. ;) Whichever option you choose is dependent on your app. One thing to keep in mind is that users hate being restricted to a specific set of options. And yeah, Apple allows almost anything that doesn't use any private APIs. I have an app right now that subclasses `UIAlertView` to add a `UITextField` without any problems. And in your case, all you're doing is making a `UIButton` that *happens* to move with the keyboard! – Chris Long Dec 22 '09 at 21:31
  • yeah my App is so easy it would probably take everyone this forum about two seconds. i just need ability for user to input numbers with decimals. so i'll probably take a stab at your idea. I really appreciate your help Chris, and don't be surprised to see me on here again for another question regarding my painfully simple App :) – Zach Smith Dec 22 '09 at 21:33
  • `UIPickerView`s aren't nearly as threatening as they seem. Your view controller can be both the datasource and the delegate, and you can pretty much copy and paste the method declarations from the Protocol References on Apple's site. – Frank Schmitt Dec 22 '09 at 22:52
1

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.

Thomas Müller
  • 15,565
  • 6
  • 41
  • 47
0

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

bpapa
  • 21,409
  • 25
  • 99
  • 147
0

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

Tim
  • 2,794
  • 1
  • 17
  • 10