无法在iOS中使用NSNumberFormatter进行货币转换

我有一个UITextField从我的应用程序中的用户接收数字input。 然后在我的shouldChangeCharactersInRange委托方法中使用NSNumberFormatter将此文本字段的值转换为货币格式。 当我input号码“12345678”时,号码被正确地转换为$ 123456.78(这些号码一次input一位数,直到这一点,一切正常)。 但是,如果在此之后input另一个数字(例如9),而不是显示“1234567.89”,则会显示数字“1234567.88”。 如果在此之后input另一个数字,则会在此之后input完全不同的数字(我正在使用应用程序中的数字键盘input数字,下面是我的代码:

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; [formatter setNumberStyle:NSNumberFormatterCurrencyStyle]; modifiedValue = [formatter stringFromNumber:[NSNumber numberWithFloat:[modifiedValue floatValue]]]; textField.text = modifiedValue; 

导致这种不寻常的转换的线是这样的:

 modifiedValue = [formatter stringFromNumber:[NSNumber numberWithFloat:[modifiedValue floatValue]]]; 

任何人都可以看到这是为什么?

在进行string – >浮点转换时,这可能是舍入错误。 处理货币时不应该使用浮动。 你可以改用NSDecimalNumber

 NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; [formatter setNumberStyle:NSNumberFormatterCurrencyStyle]; // Below 2 lines if converting from a "currency" string NSNumber *modifiedNumber = [formatter numberFromString:modifiedValue]; // To convert from the currency string to a number object NSDecimalNumber *decimal = [NSDecimalNumber decimalNumberWithDecimal:[modifiedNumber decimalValue]]; // OR the below line if converting from a non-currency string NSDecimalNumber *decimal = [NSDecimalNumber decimalNumberWithString:modifiedValue]; modifiedValue = [formatter stringFromNumber:decimal]; // Convert the new decimal back to a currency string 

您也可以考虑将数字格式化程序设置为宽松的 – 通常可以帮助用户input数据。

 [formatter setLenient:YES]; 

当我将数字转换为货币时,我通常运行以下代码:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *text = _textField.text; NSString *decimalSeperator = @"."; NSCharacterSet *charSet = nil; NSString *numberChars = @"0123456789"; // the number formatter will only be instantiated once ... static NSNumberFormatter *numberFormatter; if (!numberFormatter) { [numberFormatter setLocale:[NSLocale currentLocale]]; numberFormatter = [[NSNumberFormatter alloc] init]; numberFormatter.numberStyle = NSNumberFormatterCurrencyStyle; numberFormatter.maximumFractionDigits = 10; numberFormatter.minimumFractionDigits = 0; numberFormatter.decimalSeparator = decimalSeperator; numberFormatter.usesGroupingSeparator = NO; } // create a character set of valid chars (numbers and optionally a decimal sign) ... NSRange decimalRange = [text rangeOfString:decimalSeperator]; BOOL isDecimalNumber = (decimalRange.location != NSNotFound); if (isDecimalNumber) { charSet = [NSCharacterSet characterSetWithCharactersInString:numberChars]; } else { numberChars = [numberChars stringByAppendingString:decimalSeperator]; charSet = [NSCharacterSet characterSetWithCharactersInString:numberChars]; } // remove amy characters from the string that are not a number or decimal sign ... NSCharacterSet *invertedCharSet = [charSet invertedSet]; NSString *trimmedString = [string stringByTrimmingCharactersInSet:invertedCharSet]; text = [text stringByReplacingCharactersInRange:range withString:trimmedString]; // whenever a decimalSeperator is entered, we'll just update the textField. // whenever other chars are entered, we'll calculate the new number and update the textField accordingly. if ([string isEqualToString:decimalSeperator] == YES) { textField.text = text; } else { NSNumber *number = [numberFormatter numberFromString:text]; if (number == nil) { number = [NSNumber numberWithInt:0]; } textField.text = isDecimalNumber ? text : [numberFormatter stringFromNumber:number]; } return NO; // we return NO because we have manually edited the textField contents. } 

解释这一点的链接是将货币格式重新应用到更改事件上的UITextField

希望这个作品!