如何配置NumberFormatter实现整数不显示小数部分的货币格式化
解决NumberFormatter的欧元格式化需求
刚好之前处理过类似的货币格式化需求,你要的效果是整数不显示小数部分,非整数强制显示两位小数,现有代码的问题在于默认的currency样式会强制保留两位小数(哪怕是整数),哪怕设置了alwaysShowsDecimalSeparator = false也没用,因为minimumFractionDigits默认是2,所以整数还是会显示.00。
这里给你两种实现方式,都能完美满足需求:
方式一:封装成扩展(推荐,复用性高)
通过给NumberFormatter写扩展,把判断逻辑和格式化逻辑封装在一起,方便后续调用:
extension NumberFormatter { // 创建基础的欧元格式化器 static func euroFormatter() -> NumberFormatter { let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.currencySymbol = "€" // 设置locale确保小数分隔符的一致性,如果你需要适配其他地区可以调整这个值 formatter.locale = Locale(identifier: "en_US_POSIX") return formatter } // 自定义格式化方法,根据数字类型调整小数位数 func formattedEuroString(from number: NSNumber) -> String? { // 判断数字是否为整数:取余1等于0就是整数 let isWholeNumber = number.doubleValue.truncatingRemainder(dividingBy: 1) == 0 if isWholeNumber { // 整数:不显示小数位 self.minimumFractionDigits = 0 self.maximumFractionDigits = 0 } else { // 非整数:强制显示两位小数 self.minimumFractionDigits = 2 self.maximumFractionDigits = 2 } return self.string(from: number) } } // 调用示例 let formatter = NumberFormatter.euroFormatter() // 整数测试 if let zeroStr = formatter.formattedEuroString(from: 0) { print(zeroStr) // 输出:0 € } if let wholeNumStr = formatter.formattedEuroString(from: 123.0) { print(wholeNumStr) // 输出:123 € } // 非整数测试 if let decimalStr1 = formatter.formattedEuroString(from: 123.9) { print(decimalStr1) // 输出:123.90 € } if let decimalStr2 = formatter.formattedEuroString(from: 12.1) { print(decimalStr2) // 输出:12.10 € }
方式二:直接写工具函数(快速实现)
如果不需要复用,直接写个简单的工具函数也能搞定:
let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.currencySymbol = "€" formatter.locale = Locale(identifier: "en_US_POSIX") func formatEuroCurrency(number: Double) -> String? { let num = NSNumber(value: number) let isWholeNumber = num.doubleValue.truncatingRemainder(dividingBy: 1) == 0 // 动态调整小数位数 formatter.minimumFractionDigits = isWholeNumber ? 0 : 2 formatter.maximumFractionDigits = isWholeNumber ? 0 : 2 return formatter.string(from: num) } // 测试 print(formatEuroCurrency(number: 0.00)!) // 0 € print(formatEuroCurrency(number: 123.90)!) // 123.90 € print(formatEuroCurrency(number: 12.1)!) // 12.10 €
关键逻辑说明
核心就是动态修改minimumFractionDigits和maximumFractionDigits:
- 当数字是整数时,把两个属性都设为0,这样就不会显示小数部分和分隔符
- 当数字是非整数时,把两个属性都设为2,强制保留两位小数,哪怕原来只有一位(比如12.1会变成12.10)
另外设置locale是为了避免不同地区的小数分隔符差异(比如欧洲部分地区用逗号作为分隔符),如果你的APP需要适配多语言,可以根据用户的系统locale来调整,而不是硬编码en_US_POSIX。
内容的提问来源于stack exchange,提问作者Dmitry Serov
相关产品推荐
相关产品推荐

