Re-Apply currency formatting to a UITextField on a change event

前端 未结 6 2149
日久生厌
日久生厌 2020-11-28 12:33

I\'m working with a UITextField that holds a localized currency value. I\'ve seen lots of posts on how to work with this, but my question is: how do I re-apply currency for

6条回答
  •  误落风尘
    2020-11-28 12:56

    This was good basis but still did not satisfy my app needs. Here is what I cooked to help it. I understand that code is actually cumbersome and it is here rather to give a clue and may be to get more elegant solution.

    - (BOOL)textField:(UITextField *)aTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {   
            if (aTextField == myAmountTextField) {
                    NSString *text = aTextField.text;
                    NSString *decimalSeperator = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator];
                    NSString *groupSeperator = [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator];
    
                    NSCharacterSet *characterSet = nil;
                    NSString *numberChars = @"0123456789";
                    if ([text rangeOfString:decimalSeperator].location != NSNotFound)
                            characterSet = [NSCharacterSet characterSetWithCharactersInString:numberChars];
                    else
                            characterSet = [NSCharacterSet characterSetWithCharactersInString:[numberChars stringByAppendingString:decimalSeperator]];
    
                    NSCharacterSet *invertedCharSet = [characterSet invertedSet];   
                    NSString *trimmedString = [string stringByTrimmingCharactersInSet:invertedCharSet];
                    text = [text stringByReplacingCharactersInRange:range withString:trimmedString];
    
                    if ([string isEqualToString:decimalSeperator] == YES ||
                        [text rangeOfString:decimalSeperator].location == text.length - 1) {
                            [aTextField setText:text];
                    } else {
                            /* Remove group separator taken from locale */
                            text = [text stringByReplacingOccurrencesOfString:groupSeperator withString:@""];
    
    
                            /* Due to some reason, even if group separator is ".", number
                            formatter puts spaces instead. Lets handle this. This all should
                            be done before converting to NSNUmber as otherwise we will have
                            nil. */
                            text = [text stringByReplacingOccurrencesOfString:@" " withString:@""];
                            NSNumber *number = [numberFormatter numberFromString:text];
                            if (number == nil) {
                                    [textField setText:@""];
                            } else {
                                    /* Here is what I call "evil miracles" is going on :)
                                    Totally not elegant but I did not find another way. This
                                    is all needed to support inputs like "0.01" and "1.00" */
                                    NSString *tail = [NSString stringWithFormat:@"%@00", decimalSeperator];
                                    if ([text rangeOfString:tail].location != NSNotFound) {
                                            [numberFormatter setPositiveFormat:@"#,###,##0.00"];
                                    } else {
                                            tail = [NSString stringWithFormat:@"%@0", decimalSeperator];
                                            if ([text rangeOfString:tail].location != NSNotFound) {
                                                    [numberFormatter setPositiveFormat:@"#,###,##0.0#"];
                                            } else {
                                                    [numberFormatter setPositiveFormat:@"#,###,##0.##"];
                                            }
                                    }
                                    text = [numberFormatter stringFromNumber:number];
                                    [textField setText:text];
                            }
                    }
    
                    return NO;
            }
            return YES;
    }
    

    Number formatter is initialized in a way like this:

    numberFormatter = [[NSNumberFormatter alloc] init]; 
    [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    numberFormatter.roundingMode = kCFNumberFormatterRoundFloor;
    

    It is locale aware, so should work fine in different locale setups. It also supports the following inputs (examples):

    0.00 0.01

    1,333,333.03

    Please somebody improve this. Topic is kind of interesting, no elegant solution exists so far (iOS has not setFormat() thing).

提交回复
热议问题