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