Как заставить знак-символ на выходе NSNumberFormatter
Я хочу использовать средство форматирования чисел для генерации выходных данных, чтобы число автоматически форматировалось для языкового стандарта пользователя, но я хочу, чтобы оно работало так же, как "%+.1f" в printf(), для которого всегда указывается знак.
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
nf.numberStyle = NSNumberFormatterDecimalStyle;
nf.maximumFractionDigits = 1;
double val = 3.1234;
label.text = [NSString stringWithFormat: @"XXX %@ XXX", [nf stringFromNumber: [NSNumber numberWithDouble: val]]];
Я хочу, чтобы лейбл выходил "XXX +3.1 XXX" в США и подходящая, но эквивалентная строка для любого другого места. Единственное, что я могу найти, это setPositiveFormat:
а также setPositivePrefix:
,
Но я не хочу устанавливать формат, так как я не знаю, как форматировать числа в других странах; Я не знаю, используется ли знак плюс для обозначения положительного числа на арабском или русском языке или какой-либо другой культуре, о которой я не думал. Например, я знаю, что в европейских странах десятичные точки, запятые, пробелы и т. Д. Имеют разное значение по сравнению с США. Может ли то же самое быть для знаков +/-?
Что я делаю в настоящее время:
label.text = [NSString stringWithFormat: @"XXX %s%@ XXX", (val < 0) ? "" : "+",
[nf stringFromNumber: [NSNumber numberWithDouble: val]]];
Но это предполагает, что "+" и "-" являются правильными для всех форматов.
Я уверен, что это должно быть там, потому что это стандартная вещь форматирования, которая была в printf() с темных веков...
7 ответов
Как насчет этого:
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
nf.numberStyle = NSNumberFormatterDecimalStyle;
nf.maximumFractionDigits = 1;
double val = 3.1234;
NSString *sign = (val < 0) ? [nf minusSign] : [nf plusSign];
NSString *num = [nf stringFromNumber:@(abs(val))]; // avoid double negative
label.text = [NSString stringWithFormat: @"XXX %@%@ XXX", sign, num];
Возможно, вам придется проверить, если num
имеет sign
префикс или нет, поэтому он не отображается дважды.
Редактировать: после некоторой игры было определено, для стиля "Десятичный", что ни одна текущая локаль не использует positivePrefix
, Никакая текущая локаль не использует plusSign
кроме стандартных +
персонаж. Никакая текущая локаль не использует negativePrefix
это отличается от minusSign
, Ни одна текущая локаль не использует либо positiveSuffix
или же negativeSuffix
,
Так что проще было бы сделать:
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
nf.numberStyle = NSNumberFormatterDecimalStyle;
nf.maximumFractionDigits = 1;
[nf setPositivePrefix:[nf plusSign]];
[nf setNegativePrefix:[nf minusSign]];
label.text = [nf stringFromNumber:@(val)];
В этом случае все просто, просто добавьте префикс:
nf.positivePrefix= nf.plusSign;
Хотя он не будет использовать языковой стандарт пользователя, вы можете сделать следующее, чтобы сгенерировать знак +/- без дорогостоящих затрат NSNumberFormatter
:
// assume 'number' is an NSNumber
label.text = [NSString stringWithFormat:@"%+.02f", [number floatValue]];
Простой случай:
let f = NumberFormatter()
f.numberStyle = .currency
f.positivePrefix = f.plusSign + f.currencySymbol
Валютный кейс:
Взломать нужно, потому что установка префикса на plusSign только удалит символ валюты.
let f = NumberFormatter()
f.numberStyle = .currency
f.positivePrefix = f.plusSign + f.currencySymbol
В зависимости от локали немного больше работы. Символ валюты может быть до или после, но это, вероятно, другая тема.
Редактировать:
Даже если это другая тема, я бы сказал, что возможное решение описанной выше проблемы заключается в создании подкласса NSNumberFormatter:
override func string(from number: NSNumber) -> String? {
returns ( number.doubleValue >= 0 ? super.plusSign : "" ) + super.string(from: number)
}
Таким образом, NSNumberFormatter должен управлять валютной позицией, в то время как ваш подкласс просто добавляет знак +. Нет времени, чтобы проверить это подробно, но, по крайней мере, это подход.
Многоразовый форматер в swift:
var numberFormatter: NSNumberFormatter {
let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
formatter.locale = NSLocale(localeIdentifier: "it_IT")//your Locale
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 0
formatter.positivePrefix = formatter.plusSign
return formatter
}
Тогда используйте это:
let myDoubleValue = 12.00
let myStringNumber = numberFormatter.stringFromNumber(myDoubleValue)!
Базовый язык форматирования для NSNumberFormatter
не содержит каких-либо положений о том, что вы хотите сделать, - это позволит вам указать локализованный положительный знак для показателей, но не для всей форматированной строки. И не делает NSLocale
кажется, сделать доступным локализованный положительный знак.
Помимо создания фиктивной строки с показателем степени, вытягивания локализованного положительного знака и соединения окончательно отформатированной строки вручную, я думаю, вам не повезло.
Я не думаю, что какой-либо из предыдущих ответов на самом деле будет учитывать все, что вы упомянули в своем вопросе.
Правда, что
NumberFormatter
не имеет возможности установить знак плюса, видимый для всех положительных чисел при форматировании значений валюты.
Кроме того, замена префиксов и суффиксов, скорее всего, нарушит формат для некоторых регионов, и постоянная замена префикса будет работать только в том случае, если в установленном языковом стандарте используется символ валюты слева.
Простой способ решить эту проблему без потери форматирования локали можно увидеть ниже:
var value: Double = 3.1234
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.maximumFractionDigits = 1
if value > 0 {
return formatter.string(for: value.negated())?.replacingOccurrences(
of: formatter.minusSign,
with: formatter.plusSign
)
} else {
return formatter.string(for: value)
}
Хотя это можно рассматривать как
hack
, это эффективный способ добиться всего, о чем вы упомянули, без ручного написания средства форматирования чисел.