NSLocale货币符号,显示金额值之前或之后

我正在使用StoreKit在我的应用程序中实现应用内购买商店。

我有一个定制设计,这意味着价格的价值应该是白色和大,货币符号更小,更暗,并与价格值的顶部对齐。

通过在SKproductpriceLocale属性中使用NSLocale ,以及price属性中的price值,我可以毫无问题地获得货币符号。

我的问题是知道何时应该在价格之前加上货币符号以及何时将价格放在价格之后。

例子:

  • $ 5,99
  • 0,79€

我可以轻松地使用NSNumberFormatter来“开箱即用”,但由于我的布局为值和货币符号定义了不同的样式,我发现自己处于需要更多手动解决方法的位置。

有什么想法吗 ?

区域设置对象似乎不直接提供此信息,但数字格式化程序当然必须知道它。 您不应该直接询问(新式)数字格式器的format ,尽管这可能有用,然后您可以在格式字符串中查找货币符号¤

可能更好的方法是创建一个CFNumberFormatter ,它明确允许您查看其格式,然后检查该字符串:

 // NSLocale and CFLocale are toll-free bridged, so if you have an existing // NSNumberFormatter, you can get its locale and use that instead. CFLocaleRef usLocale = CFLocaleCreate(NULL, CFSTR("en_US")); CFNumberFormatterRef usFormatter = CFNumberFormatterCreate(NULL, usLocale, kCFNumberFormatterCurrencyStyle); CFLocaleRef frLocale = CFLocaleCreate(NULL, CFSTR("fr_FR")); CFNumberFormatterRef frFormatter = CFNumberFormatterCreate(NULL, frLocale, kCFNumberFormatterCurrencyStyle); NSString * usString = (__bridge NSString *)CFNumberFormatterGetFormat(usFormatter); NSString * frString = (__bridge NSString *)CFNumberFormatterGetFormat(frFormatter); NSUInteger loc = ([usString rangeOfString:@"¤"]).location; NSLog(@"Currency marker at beginning for US? %@", (loc == 0) ? @"YES" : @"NO"); loc = ([frString rangeOfString:@"¤"]).location; NSLog(@"Currency marker at end for FR? %@", (loc == [frString length] - 1) ? @"YES" : @"NO"); 

您拥有SKProduct实例中所需的一切。 只需结合使用NSNumberFormatter就可以了。

 NSNumberFormatter *priceFormatter = [[NSNumberFormatter alloc] init]; [priceFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; for (SKProduct *product in response.products) { [priceFormatter setLocale:product.priceLocale]; NSLog(@"Price for %@ is: %@",product.localizedTitle,[priceFormatter stringFromNumber:product.price]); } 

Swift 3+

 let priceFormatter = NumberFormatter() priceFormatter.numberStyle = .currency for product in response.products { priceFormatter.locale = product.priceLocale let localizedPrice = priceFormatter.string(from: product.price) print("Price for \(product.localizedTitle) is: \(localizedPrice)") } 

我用这个解决方案(Swift):

 let currencyFormat = CFNumberFormatterGetFormat(CFNumberFormatterCreate(nil, locale, .CurrencyStyle)) as NSString let positiveNumberFormat = currencyFormat.componentsSeparatedByString(";")[0] as NSString let currencySymbolLocation = positiveNumberFormat.rangeOfString("¤").location return (currencySymbolLocation == 0) ? .Before : .After 

接受的答案应该是固定的,因为CFNumberFormatterGetFormat有时(对于某些语言环境)返回双值: ¤##,#00.0;-¤##,#00.0包括负数格式。 确保解析该字符串。

我的解决方案是设置小数样式并设置最小有效位数。

 static NSNumberFormatter *NumberFormatter; if (!NumberFormatter) { NumberFormatter = [[NSNumberFormatter alloc] init]; [NumberFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; [NumberFormatter setUsesSignificantDigits:YES]; [NumberFormatter setMinimumSignificantDigits:2]; } NSString *formattedNumberString = [NumberFormatter stringFromNumber:@(valueInEuro)]; NSString *stringInEuro = [NSString stringWithFormat:@"€ %@", formattedNumberString]; 

我已经创建了SKProduct的扩展,将它们放在属于imho的地方。

 extension SKProduct { var localizedPrice: String { let numberFormatter = NSNumberFormatter() numberFormatter.numberStyle = .CurrencyStyle numberFormatter.locale = self.priceLocale numberFormatter.formatterBehavior = .Behavior10_4 return numberFormatter.stringFromNumber(self.price)! } } 

顺便提一下,这种格式化方式也正是Apple 在应用程序内购买编程指南“ 检索产品信息 ”部分中所建议的。

斯威夫特3

Locale上的扩展function:

 extension Locale { func IsCurrenySymbolAtStart() -> Bool { let currencyFormatter = NumberFormatter() currencyFormatter.numberStyle = .currency currencyFormatter.locale = self let positiveFormat = currencyFormatter.positiveFormat as NSString let currencySymbolLocation = positiveFormat.range(of: "¤").location return (currencySymbolLocation == 0) } } 

用法:

 let displayCurrencySymbolAtStart = NSLocale.current.IsCurrenySymbolAtStart()