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

前端 未结 6 2152
日久生厌
日久生厌 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:48

    This answer builds a little on Michael Klosson's code to fix some regional currency bugs, some locations caused his code to always spit out a 0 value in the final conversion back to textField string. I've also broke down the newText assignment to make it easier for some of us newer coders to digest, the nesting is tiresome for me sometimes. I logged out all NSLocale location options and their maximumFractionDigits value when an NSNUmberFormatter is set to them. I've found there were only 3 possibilities. Most use 2, some others use none, and a few use 3. This textfield delegate method handles all 3 possibilities, to ensure proper format based on region.

    Here is my textField delegate method, mainly just a rewrite of Michael's code, but with the newText assignment expanded out, regional decimal support added, and using NSDecimalNumbers as thats what I'm storing in my core data model anyway.

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
            // get the format symbols
            NSNumberFormatter *currencyFormatter = self.currencyFormatter;
            NSString *currencySymbol = currencyFormatter.currencySymbol;
            NSString *groupSeperator = currencyFormatter.groupingSeparator;
            NSString *decimalSeperator = currencyFormatter.decimalSeparator;
    
            // strip all the format symbols to leave an integer representation
            NSString* newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
            newText = [newText stringByReplacingOccurrencesOfString:currencySymbol withString:@""];
            newText = [newText stringByReplacingOccurrencesOfString:groupSeperator withString:@""];
            newText = [newText stringByReplacingOccurrencesOfString:decimalSeperator withString:@""];
    
            NSDecimalNumber *newValue = [NSDecimalNumber decimalNumberWithString:newText];
    
            if ([newText length] == 0 || newValue == 0)
                textField.text = nil;
            else if ([newText length] > currencyFormatter.maximumSignificantDigits) {
        //      NSLog(@"We've maxed out the digits");
                textField.text = textField.text;
            } else {
                // update to new value
                NSDecimalNumber *divisor;
                // we'll need a number to divide by if local currency uses fractions
                switch (currencyFormatter.maximumFractionDigits) {
                    // the max fraction digits tells us the number of decimal places
                    // divide accordingly based on the 3 available options
                    case 0:
        //              NSLog(@"No Decimals");
                        divisor = [NSDecimalNumber decimalNumberWithString:@"1.0"];
                        break;
                    case 2:
        //              NSLog(@"2 Decimals");
                        divisor = [NSDecimalNumber decimalNumberWithString:@"100.0"];
                        break;
                    case 3:
        //              NSLog(@"3 Decimals");
                        divisor = [NSDecimalNumber decimalNumberWithString:@"1000.0"];
                        break;
                    default:
                        break;
                }
                NSDecimalNumber *newAmount = [newValue decimalNumberByDividingBy:divisor];
                textField.text = [currencyFormatter stringFromNumber:newAmount];
            }
            return NO;
        }
    

提交回复
热议问题