1

I would like the user to type an amount in a textfield and I want the value to be formatted as it is being typed. Which means as the user types in the 4th digit, a comma appears at the appropriate spot denoting the thousands. example: 3,450

Right now,I am trying to use the textfield delegate method "shouldChangeCharactersInRange" and NSNumberFormatter. Unfortunately I haven't had any success. Could someone point me in the right direction? thank you!

Mark Adams
  • 30,776
  • 11
  • 77
  • 77
serge2487
  • 441
  • 2
  • 9
  • 23

1 Answers1

4

One option is to overlay a UILabel with a transparent background on top of your UITextField. Register as the delegate of the UITextField and implement:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

Then every time the user types, this method will be called allowing you to take the new value, convert it to an integer and pass it through an NSNumberFormatter, then update the UILabel to show this formatted value.

static NSNumberFormatter *formatter;

- (BOOL)textField:(UITextField *)aTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{   
    NSString *textFieldValue = [aTextField.text stringByAppendingString:string];

    if (range.length > 0)
        textFieldValue = [aTextField.text substringToIndex:range.location];

    if ([textFieldValue isEqualToString:@""])
        self.formattedLabel.text = textFieldValue;
    else
    {
        NSDecimalNumber *newValue = [[NSDecimalNumber alloc] initWithString:textFieldValue];
        if (!formatter) formatter = [[NSNumberFormatter alloc] init];
        formatter.numberStyle = NSNumberFormatterDecimalStyle;
        self.formattedLabel.text = [formatter stringFromNumber:newValue];
    }

    return YES;
}
Mark Adams
  • 30,776
  • 11
  • 77
  • 77
  • thanks for the tip! I tried it using NSDecimalNumber instead of integer. It works however the label is one digit behind. So if i click in my text field and enter "3",the label displays "NaN". And then if i enter a "4", it displays $3.00, etc... how do i fix this??What is "NaN? Do you know any other way than using a invisible label?thanks. – serge2487 Mar 03 '11 at 23:31
  • Try using the `string` argument instead of `textField.text`. I've updated my example. NaN means Not a Number. – Mark Adams Mar 03 '11 at 23:33
  • hmmm i see. my textField displays one character at a time now and I get NaN whenever I start deleting. – serge2487 Mar 04 '11 at 00:46
  • Now that I can actually test the code I write, I got this working. Updating my example again. – Mark Adams Mar 04 '11 at 04:10
  • thanks Mark, I appreciate the help. Could you explain the if statement at the end, i don't understand the logic behind it. – serge2487 Mar 04 '11 at 05:09
  • The last if makes sure that when we're deleting the last character that it won't just end up throwing NaN back at us. So we only do number formatting if there's actually a value in the text field to format. – Mark Adams Mar 04 '11 at 05:52