NSLocale currency symbol, show before or after amount value

假装没事ソ 提交于 2019-12-21 04:03:41

问题


I am using StoreKit to implement an in app purchase store in my application.

I have a custom design and it means that the value of the price should be white and large, and the currency symbol smaller, darker and aligned to the top of the price value.

I can get the currency symbol without any problems by using the NSLocale in SKproduct's priceLocale property, and the value of the price in the price property.

My problem is knowing when I should put the currency symbol before the price and when to put it after the price.

Examples:

  • $5,99
  • 0,79€

I could easily use the NSNumberFormatter to get this worked out "out of the box", but since my layout defines a different style for the value and currency symbol, I've found myself in a position where a more manual workaround is required.

Any thoughts ?


回答1:


The locale object doesn't seem to provide this information directly, but of course the number formatter must know it. You're not supposed to ask (new-style) number formatters for their format directly, although that'll probably work, and you can then look for the currency symbol, ¤, in the format string.

Possibly better would be to create a CFNumberFormatter, which does explicitly allow you to view its format, and then inspect that string:

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



回答2:


You have everything you need in your SKProduct instance. Just use NSNumberFormatter in conjunction and that's it.

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



回答3:


I use this solution (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

The accepted answer should be fixed since the CFNumberFormatterGetFormat sometimes (for some locales) returns double value: ¤##,#00.0;-¤##,#00.0 which includes a negative number format. Make sure to parse that string.




回答4:


My solution for this was to set the decimal style and set the minimum number of significant digits.

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



回答5:


I have created an extension of SKProduct, putting things where they belong 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)!
    }
}

That way of formatting is, by the way, also exactly what Apple suggests in the In-App Purchase Programming Guide, section Retrieving Product Information.




回答6:


Swift 3

An extension function on 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)
    }
}

Usage:

let displayCurrencySymbolAtStart = NSLocale.current.IsCurrenySymbolAtStart()


来源:https://stackoverflow.com/questions/12253594/nslocale-currency-symbol-show-before-or-after-amount-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!