Símbolo de moneda NSLocale, mostrar valor antes o después de la cantidad

Estoy usando StoreKit para implementar una tienda de compras en la aplicación en mi aplicación.

Tengo un layout personalizado y significa que el valor del precio debe ser blanco y grande, y el símbolo de moneda más pequeño, más oscuro y alineado a la parte superior del valor del precio.

Puedo get el símbolo de moneda sin ningún problema utilizando la NSLocale SKproduct NSLocale en SKproduct y el valor del precio en la propiedad de price .

Mi problema es saber cuándo debo poner el símbolo de la moneda antes del precio y cuándo ponerlo después del precio.

Ejemplos:

  • $ 5,99
  • 0,79 €

Podría usar fácilmente el NSNumberFormatter para que esto NSNumberFormatter "fuera de la caja", pero como mi layout define un estilo diferente para el valor y el símbolo de moneda, me he encontrado en una position en la que se requiere una solución más manual.

Alguna idea ?

El object de la configuration regional no parece proporcionar esta información directamente, pero, por supuesto, el formateador de numbers debe saberlo. Se supone que no debe pedir formadores de numbers (estilo nuevo) para su format directamente, aunque eso probablemente funcione, y luego puede search el símbolo de moneda, ¤ , en la cadena de formatting.

Posiblemente mejor sería crear un CFNumberFormatter , que explícitamente te permite ver su formatting, y luego inspeccionar esa cadena:

 // 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"); 

Tienes todo lo que necesitas en tu instancia de SKProduct . Solo use NSNumberFormatter en conjunción y eso es todo.

 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)") } 

Yo uso esta solución (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 

La respuesta aceptada debería ser corregida ya que el CFNumberFormatterGetFormat devuelve el doble valor a veces (para algunos locales): ¤##,#00.0;-¤##,#00.0 que incluye un formatting de número negativo. Asegúrate de analizar esa cadena.

Mi solución para esto fue establecer el estilo decimal y establecer el número mínimo de dígitos significativos.

 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]; 

He creado una extensión de SKProduct, poniendo las cosas donde pertenecen.

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

Esa forma de formateo es, por cierto, también exactamente lo que sugiere Apple en la Guía de progtwigción de compra en la aplicación , sección Recuperar información del producto .

Swift 3

Una function de extensión en la Locale :

 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) } } 

Uso:

 let displayCurrencySymbolAtStart = NSLocale.current.IsCurrenySymbolAtStart()