What is the best way to enter numeric values ​​with decimal points?

In my application, users should be able to enter numeric values ​​with decimal places. The iPhone does not provide a keyboard that is suitable for this purpose - only a numeric keypad and a keyboard with numbers and symbols.

Is there an easy way to use the latter and prevent the input of odd input without having to re-express the final result?

Thank!

+50
iphone cocoa-touch
Nov 09 '08 at 19:51
source share
11 answers

A more elegant solution may also be the easiest.

You do not need a decimal separator

Why? Because you can just pull it out of user input. For example, in the US locale, when you need to enter $ 1.23, you start by entering the numbers 1-2-3 (in that order). In the system, as you enter each character, this will be recognized as:

  • user enters 1: $ 0.01
  • user enters 2: $ 0.12
  • user enters 3: $ 1.23

Notice how we determined the decimal separator based on user input. Now, if the user wants to enter $ 1.00, they will simply enter the numbers 1-0-0.

In order for your code to process currencies in different language standards, you need to get the maximum digits in the currency. This can be done using the following code snippet:

NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init]; [currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; int currencyScale = [currencyFormatter maximumFractionDigits]; 

For example, the Japanese yen has a maximum fraction of 0. Therefore, when working with the yen, there is no decimal separator, and therefore you don’t even have to worry about fractional amounts.

This approach to the problem allows you to use the numeric input keyboard provided by Apple without the headaches of custom keyboards, validation, etc.

+49
Nov 26 '08 at 18:03
source share

I think it would be nice to note that with iOS 4.1 you can use the new UIKeyboardTypeDecimalPad .

So now you just need to:

 myTextField.keyboardType=UIKeyboardTypeDecimalPad; 
+52
Feb 13 2018-11-11T00:
source share

Here is an example of the solution proposed in the accepted answer. This does not handle other currencies or anything else - in my case I needed support only for dollars, regardless of which language / currency it was normal for me:

 -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { double currentValue = [textField.text doubleValue]; //Replace line above with this //double currentValue = [[textField text] substringFromIndex:1] doubleValue]; double cents = round(currentValue * 100.0f); if ([string length]) { for (size_t i = 0; i < [string length]; i++) { unichar c = [string characterAtIndex:i]; if (isnumber(c)) { cents *= 10; cents += c - '0'; } } } else { // back Space cents = floor(cents / 10); } textField.text = [NSString stringWithFormat:@"%.2f", cents / 100.0f]; //Add this line //[textField setText:[NSString stringWithFormat:@"$%@",[textField text]]]; return NO; } 

Round and floors are important: a) because of the floating point representation, sometimes losing .00001 or something else, and b) format strings rounding any precision that we removed in the backspace.

+12
Apr 14 '10 at 10:49
source share

I wanted to do the same, with the exception of currencies, not direct decimal values.

I ended up creating a custom view that contains UITextField and UILabel. The label covers the text box, but the text box still gets the finishing touches. I use the UITextFieldTextDidChange notification to observe changes in the text box (and I used NSNumberFormatter to turn the result into a formatted currency value) to update the label.

To turn off the magnifier, which allows the user to move the insertion point, you will need to use a custom subclass of UITextField and redefine the touch of Began: withEvent: and set it to not do anything.

My solution may differ from what you need, because the decimal point is always fixed - I use the system currency setting to determine how many digits should be after the decimal point. However, the numeric keypad on it does not have a decimal point. And you cannot add any buttons on the keyboard (which is especially aggravating, because there is an empty button in the lower left corner of the keyboard that is perfect for a decimal point!) Therefore, I have no solution for this, unfortunately.

+3
Nov 10 '08 at 21:30
source share

Depending on the particular application, providing a slider where the user can select a position may be the best choice on the iphone. Then no digits should be entered at all.

+2
Nov 09 '08 at 20:27
source share

You can use the slider (as Martin vs. Lewis suggested) or the UIPickerView with a separate wheel for each of the numbers.

+2
Nov 10 '08 at 15:02
source share

I built a custom view controller with a numeric dot with a decimal point ... check it out:

http://sites.google.com/site/psychopupnet/iphone-sdk/tenkeypadcustom10-keypadwithdecimal

+2
May 11 '10 at 10:17
source share

Like iOS4.1, there is a new keyboard type, UIKeyboardTypeNumberPad, but unfortunately it does not appear in the Interface Builder selection list yet.

+1
Nov 10 '10 at 10:30
source share

Here's how to do it without using float, round () or ceil () in an agnostic form of currency.

In your view controller, configure the following instance variables (with the corresponding @property operators if this is your bag):

 @interface MyViewController : UIViewController <UITextFieldDelegate> { @private UITextField *firstResponder; NSNumberFormatter *formatter; NSInteger currencyScale; NSString *enteredDigits; } @property (nonatomic, readwrite, assign) UITextField *firstResponder; @property (nonatomic, readwrite, retain) NSNumberFormatter *formatter; @property (nonatomic, readwrite, retain) NSString *enteredDigits; @end 

and your viewDidLoad method should contain the following:

 - (void)viewDidLoad { [super viewDidLoad]; NSNumberFormatter *aFormatter = [[NSNumberFormatter alloc] init]; [aFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; currencyScale = -1 * [aFormatter maximumFractionDigits]; self.formatter = aFormatter; [aFormatter release]; } 

Then implement your UITextFieldDelegate methods as follows:

 #pragma mark - #pragma mark UITextFieldDelegate methods - (void)textFieldDidBeginEditing:(UITextField *)textField { // Keep a pointer to the field, so we can resign it from a toolbar self.firstResponder = textField; self.enteredDigits = @""; } - (void)textFieldDidEndEditing:(UITextField *)textField { if ([self.enteredDigits length] > 0) { // Get the amount NSDecimalNumber *result = [[NSDecimalNumber decimalNumberWithString:self.enteredDigits] decimalNumberByMultiplyingByPowerOf10:currencyScale]; NSLog(@"result: %@", result); } } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { // Check the length of the string if ([string length]) { self.enteredDigits = [self.enteredDigits stringByAppendingFormat:@"%d", [string integerValue]]; } else { // This is a backspace NSUInteger len = [self.enteredDigits length]; if (len > 1) { self.enteredDigits = [self.enteredDigits substringWithRange:NSMakeRange(0, len - 1)]; } else { self.enteredDigits = @""; } } NSDecimalNumber *decimal = nil; if ( ![self.enteredDigits isEqualToString:@""]) { decimal = [[NSDecimalNumber decimalNumberWithString:self.enteredDigits] decimalNumberByMultiplyingByPowerOf10:currencyScale]; } else { decimal = [NSDecimalNumber zero]; } // Replace the text with the localized decimal number textField.text = [self.formatter stringFromNumber:decimal]; return NO; } 

He only checked it with pounds and pence, but he should work with the Japanese yen. If you want to format decimals for non-military purposes, just read the NSNumberFormatter documentation and set the format / maximumFractionDigits that you want.

+1
Feb 07 2018-11-17T00:
source share

A Swift 2 implementation of Mike Weller's message, as well as only USD:

  func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { guard let str = textField.text else { textField.text = "0.00" return false } let value = (str as NSString).doubleValue var cents = round(value * 100) if string.characters.count > 0 { for c in string.characters { if let num = Int(String(c)) { cents *= 10 cents += Double(num) } } } else { cents = floor(cents / 10) } textField.text = NSString(format: "%.2f", cents/100) as String return false } 
0
Sep 24 '15 at 23:05
source share

You can use STATextField and set CurrencyRepresentation to YES, which:

Enters no more than one decimal point and that no more than two digits are entered to the right of the specified decimal point.

There is also STAATMTextField , which by default supports currency mode and text input in the bank:

Provides a text box that mimics ATM login behavior.

0
Feb 16 '16 at 5:22
source share



All Articles