我是Swift编程的新手,我一直在Xcode 8.2中创建一个简单的tip计算器应用程序,我的计算设置在我的IBAction
下面.但是当我实际运行我的应用并输入要计算的金额(例如23.45)时,它会出现超过2个小数位..currency
在这种情况下如何格式化?
@IBAction func calculateButtonTapped(_ sender: Any) { var tipPercentage: Double { if tipAmountSegmentedControl.selectedSegmentIndex == 0 { return 0.05 } else if tipAmountSegmentedControl.selectedSegmentIndex == 1 { return 0.10 } else { return 0.2 } } let billAmount: Double? = Double(userInputTextField.text!) if let billAmount = billAmount { let tipAmount = billAmount * tipPercentage let totalBillAmount = billAmount + tipAmount tipAmountLabel.text = "Tip Amount: $\(tipAmount)" totalBillAmountLabel.text = "Total Bill Amount: $\(totalBillAmount)" } }
silicon_vall.. 75
如果要强制货币为$,则可以使用此字符串初始值设定项:
String(format: "Tip Amount: $%.02f", tipAmount)
如果您希望它完全依赖于设备的区域设置,则应使用a NumberFormatter
.这将考虑货币的小数位数以及正确定位货币符号.例如,对于es_ES语言环境,double值2.4将返回"2,40€",对于jp_JP语言环境,将返回"¥2".
let formatter = NumberFormatter() formatter.locale = Locale.current // Change this to another locale if you want to force a specific locale, otherwise this is redundant as the current locale is the default already formatter.numberStyle = .currency if let formattedTipAmount = formatter.string(from: tipAmount as NSNumber) { tipAmountLabel.text = "Tip Amount: \(formattedTipAmount)" }
是的,我知道,我已添加评论说这是多余的.希望将它保留在那里以显示它可以很容易地改变. (9认同)
Camilo Orteg.. 12
如何在Swift 4中做到这一点:
let myDouble = 9999.99 let currencyFormatter = NumberFormatter() currencyFormatter.usesGroupingSeparator = true currencyFormatter.numberStyle = .currency // localize to your grouping and decimal separator currencyFormatter.locale = Locale.current // We'll force unwrap with the !, if you've got defined data you may need more error checking let priceString = currencyFormatter.string(from: NSNumber(value: myDouble))! print(priceString) // Displays $9,999.99 in the US locale
Duncan C.. 9
最好的方法是创建一个NSNumberFormatter
.(NumberFormatter
在Swift 3中.)您可以请求货币,它将设置字符串以遵循用户的本地化设置,这很有用.
如果你想强制美国格式的美元和美分字符串,你可以这样格式化:
let amount: Double = 123.45 let amountString = String(format: "$%.02f", amount)
Rob.. 9
除了其他人讨论NumberFormatter
或String(format:)
讨论之外,您可能还想考虑使用Decimal
或NSDecimalNumber
控制自己的舍入,从而避免出现浮点问题.如果你正在做一个简单的小费计算器,那可能就没有必要了.但是如果你正在做一些事情,比如在一天结束时添加提示,如果你没有对数字进行舍入和/或使用十进制数进行数学计算,则可能会引入错误.
所以,继续配置你的格式化程序:
let formatter: NumberFormatter = { let _formatter = NumberFormatter() _formatter.numberStyle = .decimal _formatter.minimumFractionDigits = 2 _formatter.maximumFractionDigits = 2 _formatter.generatesDecimalNumbers = true return _formatter }()
然后,使用十进制数字:
let string = "2.03" let tipRate = Decimal(sign: .plus, exponent: -3, significand: 125) // 12.5% guard let billAmount = formatter.number(from: string) as? Decimal else { return } let tip = (billAmount * tipRate).rounded(2) guard let output = formatter.string(from: tip as NSDecimalNumber) else { return } print("\(output)")
哪里
extension Decimal { /// Round `Decimal` number to certain number of decimal places. /// /// - Parameters: /// - scale: How many decimal places. /// - roundingMode: How should number be rounded. Defaults to `.plain`. /// - Returns: The new rounded number. func rounded(_ scale: Int, roundingMode: RoundingMode = .plain) -> Decimal { var value = self var result: Decimal = 0 NSDecimalRound(&result, &value, scale, roundingMode) return result } }
显然,您可以使用适合您正在使用的货币的任何数字替换所有上述"2位小数"引用(或者可能使用变量作为小数位数).
如果要强制货币为$,则可以使用此字符串初始值设定项:
String(format: "Tip Amount: $%.02f", tipAmount)
如果您希望它完全依赖于设备的区域设置,则应使用a NumberFormatter
.这将考虑货币的小数位数以及正确定位货币符号.例如,对于es_ES语言环境,double值2.4将返回"2,40€",对于jp_JP语言环境,将返回"¥2".
let formatter = NumberFormatter() formatter.locale = Locale.current // Change this to another locale if you want to force a specific locale, otherwise this is redundant as the current locale is the default already formatter.numberStyle = .currency if let formattedTipAmount = formatter.string(from: tipAmount as NSNumber) { tipAmountLabel.text = "Tip Amount: \(formattedTipAmount)" }
如何在Swift 4中做到这一点:
let myDouble = 9999.99 let currencyFormatter = NumberFormatter() currencyFormatter.usesGroupingSeparator = true currencyFormatter.numberStyle = .currency // localize to your grouping and decimal separator currencyFormatter.locale = Locale.current // We'll force unwrap with the !, if you've got defined data you may need more error checking let priceString = currencyFormatter.string(from: NSNumber(value: myDouble))! print(priceString) // Displays $9,999.99 in the US locale
最好的方法是创建一个NSNumberFormatter
.(NumberFormatter
在Swift 3中.)您可以请求货币,它将设置字符串以遵循用户的本地化设置,这很有用.
如果你想强制美国格式的美元和美分字符串,你可以这样格式化:
let amount: Double = 123.45 let amountString = String(format: "$%.02f", amount)
除了其他人讨论NumberFormatter
或String(format:)
讨论之外,您可能还想考虑使用Decimal
或NSDecimalNumber
控制自己的舍入,从而避免出现浮点问题.如果你正在做一个简单的小费计算器,那可能就没有必要了.但是如果你正在做一些事情,比如在一天结束时添加提示,如果你没有对数字进行舍入和/或使用十进制数进行数学计算,则可能会引入错误.
所以,继续配置你的格式化程序:
let formatter: NumberFormatter = { let _formatter = NumberFormatter() _formatter.numberStyle = .decimal _formatter.minimumFractionDigits = 2 _formatter.maximumFractionDigits = 2 _formatter.generatesDecimalNumbers = true return _formatter }()
然后,使用十进制数字:
let string = "2.03" let tipRate = Decimal(sign: .plus, exponent: -3, significand: 125) // 12.5% guard let billAmount = formatter.number(from: string) as? Decimal else { return } let tip = (billAmount * tipRate).rounded(2) guard let output = formatter.string(from: tip as NSDecimalNumber) else { return } print("\(output)")
哪里
extension Decimal { /// Round `Decimal` number to certain number of decimal places. /// /// - Parameters: /// - scale: How many decimal places. /// - roundingMode: How should number be rounded. Defaults to `.plain`. /// - Returns: The new rounded number. func rounded(_ scale: Int, roundingMode: RoundingMode = .plain) -> Decimal { var value = self var result: Decimal = 0 NSDecimalRound(&result, &value, scale, roundingMode) return result } }
显然,您可以使用适合您正在使用的货币的任何数字替换所有上述"2位小数"引用(或者可能使用变量作为小数位数).
你可以为字符串或Int创建一个扩展,我会用String显示一个例子
extension String{ func toCurrencyFormat() -> String { if let intValue = Int(self){ let numberFormatter = NumberFormatter() numberFormatter.locale = Locale(identifier: "ig_NG")/* Using Nigeria's Naira here or you can use Locale.current to get current locale, please change to your locale, link below to get all locale identifier.*/ numberFormatter.numberStyle = NumberFormatter.Style.currency return numberFormatter.string(from: NSNumber(value: intValue)) ?? "" } return "" } }
链接以获取所有区域设置标识符
您可以像这样进行转换:此func转换可随时为您保留maximumFractionDigits
static func df2so(_ price: Double) -> String{ let numberFormatter = NumberFormatter() numberFormatter.groupingSeparator = "," numberFormatter.groupingSize = 3 numberFormatter.usesGroupingSeparator = true numberFormatter.decimalSeparator = "." numberFormatter.numberStyle = .decimal numberFormatter.maximumFractionDigits = 2 return numberFormatter.string(from: price as NSNumber)! }
我在Model类中创建它,然后在调用时可以接受另一个类,例如
print("InitData: result convert string " + Model.df2so(1008977.72)) //InitData: result convert string "1,008,977.72"