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

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

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

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

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

Примеры:

  • $5,99
  • 0,79€

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

Есть предположения ?


person Daniel    schedule 03.09.2012    source источник
comment
Не могли бы вы проанализировать строку, созданную NSNumberFormatter, ища нечисловые подстроки как в начале, так и в конце строки, а затем оценить, какая из них не пуста?   -  person warrenm    schedule 04.09.2012


Ответы (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");
person jscs    schedule 03.09.2012
comment
Это очень интересно. Я думаю, что могу использовать это. Спасибо. - person Daniel; 04.09.2012

В вашем экземпляре 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)")
}
person totocaster    schedule 30.04.2013
comment
Согласитесь, это лучшее решение. Я бы просто переместил первые две строки внутри цикла for за его пределы... небольшая оптимизация, но нет необходимости создавать экземпляр priceFormatter для каждого продукта в итерации. - person Luis Artola; 31.01.2014
comment
Привет, спасибо, просто продолжение, на самом деле это не решило бы мою проблему, потому что в моем случае мне нужен был определенный шрифт для строки валюты, а не значение цены, поэтому мне нужно было знать, была ли строка валюты до или после ценовое значение. - person Daniel; 18.03.2015

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

person SoftDesigner    schedule 26.04.2016

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

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];
person Fábio Oliveira    schedule 24.09.2013

Я создал расширение SKProduct, помещая вещи туда, где им и место.

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

person Sebastian Hojas    schedule 22.07.2016

Свифт 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()
person Joseph    schedule 11.09.2017