NSLocale символ валюты, показать до или после значения суммы

Я использую StoreKit внедрить магазин покупки в приложении в моем приложении.

У меня есть индивидуальный дизайн, и это означает, что значение цены должно быть белым и большим, а символ валюты меньше, темнее и выровнен по вершине значения цены.

Я могу получить символ валюты без каких-либо проблем, используя NSLocale в SKproduct"s priceLocale собственности, и стоимость цены в price имущество.

Моя проблема в том, чтобы знать, когда я должен поставить символ валюты перед ценой, а когда поставить его после цены.

Примеры:

  • $ 5,99
  • 0,79 €

Я мог бы легко использовать NSNumberFormatter чтобы получить это "из коробки", но так как мой макет определяет другой стиль для значения и символа валюты, я оказался в положении, когда требуется более ручное решение.

Какие-нибудь мысли?

6 ответов

Решение

Кажется, объект языкового стандарта не предоставляет эту информацию напрямую, но, конечно, средство форматирования чисел должно знать об этом. Вы не должны спрашивать (новый стиль) числителей для их 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]);
}

Свифт 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 который включает в себя формат отрицательного числа. Обязательно проанализируйте эту строку.

Свифт 3

Функция расширения на 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)
    }
}

Использование:

let displayCurrencySymbolAtStart = NSLocale.current.IsCurrenySymbolAtStart()

Моим решением для этого было установить десятичный стиль и установить минимальное количество значащих цифр.

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 предлагает в Руководстве по программированию покупок в приложении, раздел " Получение информации о продукте".

Другие вопросы по тегам