16

我想使用数字格式化程序来生成我的输出,所以数字会自动格式化为用户的语言环境,但我希望它像printf()中的"%+.1f"一样工作,总是有一个指定的符号。

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()中的标准格式设置...

4

6 回答 6

20

这个怎么样:

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];

您可能需要检查是否numsign前缀,所以它不会显示两次。

编辑:经过一番尝试,已经确定,对于“十进制”样式,当前语言环境没有使用positivePrefix. 当前的语言环境不使用plusSign标准字符以外的+字符。当前没有任何语言环境使用negativePrefix不同于minusSign. 当前的语言环境不使用positiveSuffixnegativeSuffix

因此,一种更简单的方法是:

NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
nf.numberStyle = NSNumberFormatterDecimalStyle;
nf.maximumFractionDigits = 1;
[nf setPositivePrefix:[nf plusSign]];
[nf setNegativePrefix:[nf minusSign]];

label.text = [nf stringFromNumber:@(val)];
于 2013-01-04T03:05:52.640 回答
11

这种情况很简单,只需添加前缀:

nf.positivePrefix= nf.plusSign;
于 2013-01-04T02:05:44.397 回答
3

虽然它不会使用用户的语言环境,但您可以执行以下操作来生成 +/- 符号,而无需花费一些昂贵的开销NSNumberFormatter

// assume 'number' is an NSNumber
label.text = [NSString stringWithFormat:@"%+.02f", [number floatValue]];
于 2015-11-09T21:50:00.237 回答
3

简单案例:

    let f = NumberFormatter()
    f.positivePrefix = f.plusSign

货币案例:

需要破解,因为将前缀设置为 plusSign only 将删除货币符号。

    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 应该管理货币头寸,而您的子类只需添加 + 号。没有时间对此进行深入测试,但至少这是一种方法。

于 2017-07-09T06:20:59.370 回答
0

底层格式化语言NSNumberFormatter您想要做的事情没有任何规定——它将允许您在 exponents 上指定一个本地化的正号,但不能为整个格式化字符串指定一个本地化的正号。NSLocale似乎也没有提供本地化的正号。

除了制作一个包含指数的虚拟字符串,将本地化的正号拉出并手动将最终格式化的字符串放在一起之外,我认为你不走运。

于 2013-01-04T02:10:54.030 回答
0

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)!
于 2016-01-19T15:44:37.803 回答