如何在NSNumberFormatter的输出上强制使用符号字符

我想使用数字格式化程序来生成我的输出,因此数字会自动格式化为用户的语言环境,但是我希望它在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()中

这个怎么样:

 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 。 当前区域设置不使用与minusSign不同的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)]; 

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

 nf.positivePrefix= nf.plusSign; 

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

 // assume 'number' is an NSNumber label.text = [NSString stringWithFormat:@"%+.02f", [number floatValue]]; 

NSNumberFormatter的基础格式化语言没有任何您想要做的规定 – 它允许您在指数上指定本地化的正号,但不能为整个格式化的字符串指定。 NSLocale似乎也没有提供本地化的正号。

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

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)! 

简单案例:

  let f = NumberFormatter() f.numberStyle = .currency f.positivePrefix = f.plusSign + f.currencySymbol 

货币案例:

需要Hack,因为仅将前缀设置为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应该管理货币位置,而子类只是在前面添加+符号。 没有时间对此进行深入测试,但至少这是一种方法。