Format currency in a UITextField

3

I need to create a UITextField to add money values. But I need the user to see the value being added in the UITextField in the order the user types. Example: User types 1 - in UITextField 0.01 appears User types 5 - UITextField appears 0,15 User types 0 - UITextField appears 1.50

Here is my problem, when the user types the 4th digit, in my case it is appearing 1,5,00 and not 15,00 as desire.

Follow the formatting code:

    NSNumberFormatter *valueTextFieldFormatter= [NSNumberFormatter new];
    [valueTextFieldFormatter setPositiveFormat:@"#0,0"];
    [valueTextFieldFormatter setNumberStyle:NSNumberFormatterDecimalStyle];

    NSString *num = [textField.text stringByReplacingOccurrencesOfString:@"," withString:@""];

    textField.text = [valueTextFieldFormatter stringFromNumber:[NSNumber numberWithInt:[num floatValue]]];

    
asked by anonymous 06.03.2014 / 01:42

4 answers

2

I did a little different. That way I have the number entered by the user formatted in UITextField (valueTextField.text) and I have a version of it with only numbers (storeValue) in case I need to do accounts and these things.

In @interface :

   NSMutableString *storeValue;
   NSNumberFormatter *numberFormatter; 

In viewDidLoad: :

    storeValue = [NSMutableString new];
    numberFormatter = [NSNumberFormatter new];
    [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    [super viewDidLoad];

And in shouldChangeCharactersInRange:

    if (textField == valueTextField) {
        if (string.length == 0) {
            int length = (storeValue.length - 1);
            if (length >= 0) {
                NSRange range = NSMakeRange(length, 1);
                [storeValue deleteCharactersInRange:range];
            };
        } else if ([textField.text length] <= 7) {
            [storeValue appendString:string];
        }

        NSString *newText = [numberFormatter stringFromNumber:[NSNumber numberWithFloat:([storeValue doubleValue] / 100)] ];
        [textField setText:[NSString stringWithFormat:@"%@",newText]];

        return NO;
    }

    return YES;
    
11.03.2014 / 05:04
6

David, there are simpler ways to solve this problem. Try changing the style of the number to NSNumberFormatterCurrencyStyle and putting a location as a reference for the formatting.

NSNumberFormatter *n = [[NSNumberFormatter alloc] init];
[n setNumberStyle:NSNumberFormatterCurrencyStyle];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"pt_BR"];
[n setLocale:locale];
NSString *saída = [n stringFromNumber:[NSNumber numberWithFloat:125.98]];

The output will be $ 125.98.

    
06.03.2014 / 03:43
3

I have something a little different in shouldChangeCharactersInRange in an application of mine working the way you want it.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if ([textField tag] == 1) { // Só para identificar o campo de moeda
        NSString *replaced = [textField.text stringByReplacingCharactersInRange:range withString:string];
        NSDecimalNumber *amount = (NSDecimalNumber*) [self.formatter numberFromString:replaced];
        if (amount == nil) {
            return NO;
        }
        short powerOf10 = 0;
        if ([textField.text isEqualToString:@""]) {
            powerOf10 = -self.formatter.maximumFractionDigits;
        } else if (range.location + self.formatter.maximumFractionDigits >= textField.text.length) {
            if (range.length) {
                powerOf10 = -range.length;
            } else {
                powerOf10 = [string length];
            }
        }
        amount = [amount decimalNumberByMultiplyingByPowerOf10:powerOf10];
        textField.text = [self.formatter stringFromNumber:amount];
        return NO;
    }

    return YES;
}

And in viewDidLoad: I have my property formatter used above:

self.formatter = [NSNumberFormatter new];
[self.formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[self.formatter setLenient:YES];
[self.formatter setGeneratesDecimalNumbers:YES];
[self.formatter setCurrencySymbol:@""];
[self.formatter setInternationalCurrencySymbol:@""];

locale is not required, as it is already set in device settings unless you want something different.

    
07.03.2014 / 12:56
1

David Batista's response was very helpful.

I'm writing the code in Swift and it worked very well.

if ((string as NSString).length == 0) {
        var length = (storeValue.length - 1);
        if (length >= 0) {
            var range = NSMakeRange(length, 1)

            storeValue.deleteCharactersInRange(range)
        }
    } else if ( (textField.text as NSString).length <= 15) {
        storeValue.appendString(string)
    }

    var newText = numberFormatter.stringFromNumber(NSNumber(double: storeValue.doubleValue/100))
    textField.text = NSString(format: "%@", newText!) as String

    return false
    
07.10.2015 / 21:14