私はユーザー入力を通貨としてフォーマットしています。私は2つのラベルとテキストフィールドを含む非常に基本的なビューコントローラを持っています。シーンは次のようになります。通貨が小数点を受け入れるかどうかを検出する方法を教えてください。
大手ラベルが値の前に記号が含まれている通貨の通貨記号を表示するように意図されます。後続ラベルは、値の後の記号を含む通貨の通貨記号を表示するためのものです。テキストフィールドは、入力されたテキストに合うように水平方向に伸縮し、後続の通貨記号は常に入力値に固定されます。未使用ラベルのtext
プロパティはnil
に設定されているため、非表示になります。
これまでのところ、すべて正常に動作します。別の通貨形式を使用するようにスキームのロケールを設定すると、ラベルに正しく入力されます。私は、次のコードで通貨記号の位置を検出しています:私は、いつでも、適用通貨の小数点区切りで、値のみを残して、テキストフィールド内の通貨記号を取り除く
internal static var currencySymbolPosition: CurrencySymbolPosition {
let currencyFormat = CFNumberFormatterGetFormat(CFNumberFormatterCreate(nil, Locale.current as CFLocale, .currencyStyle)) as NSString
let positiveNumberFormat = currencyFormat.components(separatedBy: ";")[0] as NSString
let currencySymbolLocation = positiveNumberFormat.range(of: "¤").location
let position: CurrencySymbolPosition = currencySymbolLocation == 0 ? .start : .end
return position
}
internal enum CurrencySymbolPosition {
case start
case end
}
。そのコードは次のようになります。
internal func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else { return false }
guard let currencySymbol = formatter.currencySymbol else { return false }
guard let decimalSeparator = formatter.currencyDecimalSeparator else { return false }
guard let groupingSeparator = formatter.currencyGroupingSeparator else { return false }
guard let newText = (text as NSString?)?.replacingCharacters(in: range, with: string) else { return false }
let symbolsStripped = newText.replacingOccurrences(of: currencySymbol, with: "").replacingOccurrences(of: decimalSeparator, with: "").replacingOccurrences(of: groupingSeparator, with: "")
guard let integer = Int(symbolsStripped) else { return false }
let double = Double(integer)/100
guard let formatted = formatter.string(from: double as NSNumber) else { return false }
textField.text = formatted.replacingOccurrences(of: currencySymbol, with: "").trimmingCharacters(in: .whitespaces)
return false
}
私は、これが一部の通貨では機能しないという問題を抱えています。たとえば、円は小数点を使用しないので、let double = Double(integer)/100
は機能しません。結果は常に0
です。私は円の小数点記号を検出しようとしましたが、print(formatter.currencyDecimalSeparator)
を使用して印刷するとXcodeは.
を返します。 currencyDecimalSeparator
プロパティがNumberFormatter
であるため、空の文字列が予想されていました。つまり、nil
であってはなりません。私はcurrencyDecimalSeparator
を使って、正しい値を得るために100で割るべきかどうかを判断することを望んでいました。セパレータは分割を引き起こし、一方空のcurrencyDecimalSymbol
は除算をスキップします。
このシーンは私が日本に地域を設定すると次のようになります。
これは私がチェコに地域を設定したときにシーンがどのように見えるかです:
小数点を使用しない通貨を特定して、ユーザータイプとしてテキストフィールドの書式を正しく設定できる方法はありますか?
なぜすべてを取り除くのが難しいのでしょうかそれだけですべてを戻そうとする句読点?通貨記号だけを削除してください。 – rmaddy
@rmaddyテキストフィールドを使用タイプとしてフォーマットしているため、明示的に小数点を入力する必要はありません。ロケールで通貨の小数点記号を使用しない場合は、通貨を整数からフォーマットする必要があります。ロケールで通貨の小数点記号を使用している場合は、doubleからフォーマットする必要があります。このように、両方のタイプの通貨書式が適切に設定され、ユーザーは数字以外のものを入力する必要がありません。私は自分の意図をより明確にすることを願っています。 –