私はSwiftプログラミングを初めて使い、Xcode 8.2で簡単なチップ計算アプリを作成しました。以下の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)"
}
}
通貨を強制的に$にしたい場合は、この文字列初期化子を使用できます。
String(format: "Tip Amount: $%.02f", tipAmount)
デバイスのロケール設定に完全に依存する場合は、NumberFormatter
を使用する必要があります。これは、通貨記号を正しく配置するだけでなく、通貨の小数点以下の桁数も考慮に入れます。例えば。 double値2.4は、es_ESロケールの場合は「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)"
}
これを行う最良の方法は、NSNumberFormatter
を作成することです。 (SwiftのNumberFormatter
3.)通貨を要求すると、ユーザーのローカリゼーション設定に従う文字列が設定されます。これは便利です。
米国形式のドルとセントの文字列を強制する場合は、次の方法でフォーマットできます。
let amount: Double = 123.45
let amountString = String(format: "$%.02f", amount)
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
他の人によって議論されたNumberFormatter
またはString(format:)
に加えて、Decimal
またはNSDecimalNumber
の使用を検討し、自分で丸めを制御して、浮動小数点の問題を回避することができます。単純なチップ計算機を使用している場合、おそらくそれは必要ありません。ただし、1日の終わりにヒントを追加するようなことをしている場合、数値を丸めたり、10進数を使用して計算を行わなかったりすると、エラーが発生する可能性があります。
そこで、フォーマッターを構成してください:
let formatter: NumberFormatter = {
let _formatter = NumberFormatter()
_formatter.numberStyle = .decimal
_formatter.minimumFractionDigits = 2
_formatter.maximumFractionDigits = 2
_formatter.generatesDecimalNumbers = true
return _formatter
}()
次に、10進数を使用します。
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のいずれかの拡張機能を作成できます。文字列の例を示します
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 convertはあなたがやりたいときにいつでも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"
extension Float {
var localeCurrency: String {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = .current
return formatter.string(from: self as NSNumber)!
}
}
amount = 200.02
print("Amount Saved Value ",String(format:"%.2f", amountSaving. localeCurrency))
私にとっては、0.00を返します!それにアクセスすると、Extensiontion Perfectは0.00を返します!どうして?