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

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