Значок валюты NSLocale, показывать до или после значения суммы
Я использую StoreKit
для реализации магазина покупки приложений в своем приложении.
У меня есть пользовательский дизайн, и это означает, что стоимость цены должна быть белой и большой, а символ валюты меньше, темнее и выравнивается до верхней границы цены.
Я могу получить символ валюты без каких-либо проблем, используя свойство NSLocale
in SKproduct
priceLocale
и значение цены в свойстве price
.
Моя проблема - знать, когда я должен поставить символ валюты перед ценой и когда положить ее после цены.
Примеры:
Я мог бы легко использовать NSNumberFormatter
, чтобы это получилось "из коробки", но поскольку мой макет определяет другой стиль для символа значения и валюты, я оказался в положении, когда более руководство требуется обходное решение.
Любые мысли?
Ответы
Ответ 1
Объект locale, по-видимому, не предоставляет эту информацию напрямую, но, конечно же, число форматера должно знать это. Вы не должны спрашивать (new-style) число formatters для своих 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");
Ответ 2
В вашем экземпляре 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)")
}
Ответ 3
Я использую это решение (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
, который содержит формат отрицательного числа. Обязательно проанализируйте эту строку.
Ответ 4
Моим решением для этого было установить десятичный стиль и установить минимальное количество значащих цифр.
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
Я создал расширение 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 в Руководстве по программированию при покупке приложений, раздел Получение информации о товаре.
Ответ 6
Swift 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()