番号があります0.00
。
0.01
0.12
1.23
12.34
Swiftでこれを行うにはどうすればよいですか?
Swiftの場合。テキストフィールドでの通貨形式の入力(右から左へ)
override func viewDidLoad() {
super.viewDidLoad()
textField.addTarget(self, action: #selector(myTextFieldDidChange), for: .editingChanged)
}
func myTextFieldDidChange(_ textField: UITextField) {
if let amountString = textField.text?.currencyInputFormatting() {
textField.text = amountString
}
}
extension String {
// formatting text for currency textField
func currencyInputFormatting() -> String {
var number: NSNumber!
let formatter = NumberFormatter()
formatter.numberStyle = .currencyAccounting
formatter.currencySymbol = "$"
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
var amountWithPrefix = self
// remove from String: "$", ".", ","
let regex = try! NSRegularExpression(pattern: "[^0-9]", options: .caseInsensitive)
amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count), withTemplate: "")
let double = (amountWithPrefix as NSString).doubleValue
number = NSNumber(value: (double / 100))
// if first number is 0 or all numbers were deleted
guard number != 0 as NSNumber else {
return ""
}
return formatter.string(from: number)!
}
}
UITextFieldをサブクラス化する通貨テキストフィールドを作成できます。 UIControlEvents .editingChangedのターゲットを追加します。セレクタメソッドを追加して、テキストフィールド文字列から数字をフィルタリングします。文字列からすべての数字以外をフィルタリングした後、次のようにNumberFormatterを使用して番号を再度フォーマットできます。
Swift 5以降
class CurrencyField: UITextField {
var string: String { return text ?? "" }
var decimal: Decimal {
return string.decimal /
pow(10, Formatter.currency.maximumFractionDigits)
}
var decimalNumber: NSDecimalNumber { return decimal.number }
var doubleValue: Double { return decimalNumber.doubleValue }
var integerValue: Int { return decimalNumber.intValue }
let maximum: Decimal = 999_999_999.99
private var lastValue: String?
override func willMove(toSuperview newSuperview: UIView?) {
// you can make it a fixed locale currency if needed
// Formatter.currency.locale = Locale(identifier: "pt_BR") // or "en_US", "fr_FR", etc
addTarget(self, action: #selector(editingChanged), for: .editingChanged)
keyboardType = .numberPad
textAlignment = .right
editingChanged()
}
override func deleteBackward() {
text = string.digits.dropLast().string
editingChanged()
}
@objc func editingChanged() {
guard decimal <= maximum else {
text = lastValue
return
}
text = Formatter.currency.string(for: decimal)
lastValue = text
}
}
拡張NumberFormatter {便利なinit(numberStyle:スタイル){self.init()self.numberStyle = numberStyle}}
extension Formatter {
static let currency = NumberFormatter(numberStyle: .currency)
}
extension String {
var digits: String { return filter { $0.isWholeNumber } }
var decimal: Decimal { return Decimal(string: digits) ?? 0 }
}
extension Decimal {
var number: NSDecimalNumber { return NSDecimalNumber(decimal: self) }
}
extension LosslessStringConvertible {
var string: String { return .init(self) }
}
私の最終的なコードはあなたの助けに感謝します
extension Double {
var twoDigits: Double {
let nf = NSNumberFormatter()
nf.numberStyle = NSNumberFormatterStyle.DecimalStyle
nf.minimumFractionDigits = 2
nf.maximumFractionDigits = 2
return self
}
}
var cleanText:String!
let number:String = sender.currentTitle as String!
if(amountDisplay.text != nil)
{
cleanText = String(Array(amountDisplay.text!).map{String($0)}.filter{ $0.toInt() != nil }.map{Character($0)} ) as String
cleanText = cleanText + number
}else{
cleanText = number
}
amount = (Double(cleanText.toInt()!) / 100).twoDigits
formatter.locale = NSLocale(localeIdentifier: currencies[current_currency_index])
amountDisplay.text = "\(formatter.stringFromNumber(amount!)!)"
次のコードを試してください:
struct DotNum {
private var fraction:String = ""
private var intval:String = ""
init() {}
mutating func enter(s:String) {
if count(fraction) < 2 {
fraction = s + fraction
} else {
intval = s + intval
}
}
private var sFract:String {
if count(fraction) == 0 { return "00" }
if count(fraction) == 1 { return "0\(fraction)" }
return fraction
}
var stringVal:String {
if intval == "" { return "0.\(sFract)" }
return "\(intval).\(sFract)"
}
}
var val = DotNum()
val.enter("1")
val.stringVal
val.enter("2")
val.stringVal
val.enter("3")
val.stringVal
val.enter("4")
val.stringVal
ここにSwift 2のコードがあります
@IBOutlet weak var txtAmount: UITextField!
//MARK: - UITextField Delegate -
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool{
if string.characters.count == 0 {
return true
}
let userEnteredString = textField.text ?? ""
var newString = (userEnteredString as NSString).stringByReplacingCharactersInRange(range, withString: string) as NSString
newString = newString.stringByReplacingOccurrencesOfString(".", withString: "")
let centAmount : NSInteger = newString.integerValue
let amount = (Double(centAmount) / 100.0)
if newString.length < 16 {
let str = String(format: "%0.2f", arguments: [amount])
txtAmount.text = str
}
return false //return false for exact out put
}
注:ストーリーボードまたはプログラムでtextFieldのデリゲートを接続します
ただの楽しみのために:ファイルにコピーして Thomasの答え (彼へのフルクレジット-とポイント-をお願いします)Swift 4.1スクリプト(マイナーな修正))として実行します:
dotnum.Swift:
#!/usr/bin/Swift
struct DotNum {
private var fraction:String = ""
private var intval:String = ""
init() {}
mutating func enter(_ s:String) {
if fraction.count < 2 {
fraction = s + fraction
} else {
intval = s + intval
}
}
private var sFract:String {
if fraction.count == 0 { return "00" }
if fraction.count == 1 { return "0\(fraction)" }
return fraction
}
var stringVal:String {
if intval == "" { return "0.\(sFract)" }
return "\(intval).\(sFract)"
}
}
var val = DotNum()
val.enter("1")
print(val.stringVal)
val.enter("2")
print(val.stringVal)
val.enter("3")
print(val.stringVal)
val.enter("4")
print(val.stringVal)
次に、ターミナルで実行します。
$ chmod +x dotnum.Swift
$ ./dotnum.Swift
0.01
0.21
3.21
43.21