问题
I borrowed and modified some code from SO to solve a problem where I was trying to format text that I inputted into my UITextField
s. If I use the .decimal
numberStyle
of NumberFormatter
it works (adds a comma where I need it) but if I use .currency
I can't type anything once I run the app. The UITextField
will not populate.
I've tried playing around with the locale and that doesn't seem to solve anything.
All I want to do is to show the user the "$" sign in front of the number they type as soon as they start typing into the UITextField
It's doing it with or without the digitsOnly
extension I'm using, so that doesn't seem to be causing it.
Relevant code:
case annualBill!:
if isNumeric {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.currencySymbol = "$"
let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
let numberWithOutCommas = newString.replacingOccurrences(of: ",", with: "")
let number = formatter.number(from: numberWithOutCommas)
if number != nil {
let formattedString = formatter.string(from: number!)
textField.text = formattedString
values.annualBill = Decimal(string: (textField.text?.digitsOnly)!)
print(values.annualBill ?? "NA")
} else {
textField.text = nil
}
extension String {
var digitsOnly: String {
return components(separatedBy:
NSCharacterSet.decimalDigits.inverted).joined(separator: "")
}
}
回答1:
Try this in your text field delegate.
var amountString = ""
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if !string.isValidCharacterForCurrency() {
return false
}
let formatter = NumberFormatter()
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
if string.count > 0 {
amountString += string
let decNumber = NSDecimalNumber(string: amountString).multiplying(by: 0.01)
let newString = "$" + formatter.string(from: decNumber)!
textField.text = newString
}
else {
amountString = String(amountString.dropLast())
if amountString.count > 0 {
let decNumber = NSDecimalNumber(string: amountString).multiplying(by: 0.01)
let newString = "$" + formatter.string(from: decNumber)!
textField.text = newString
}
else {
textField.text = "$0.00"
}
}
return false
}
extension String {
func isValidCharacterForCurrency() -> Bool {
let intValue = Int(self)
return !(intValue == 0 && self != "0" && self != "")
}
}
回答2:
Try this code in your extension and use it with your newString
and currencyCode such as USD
, best is to use with the number with decimal
keyboard so you wont need to check the format beforehand
public func toCurrencyFormatter(with currencyCode: String) -> String {
if NSDecimalNumber(string: self) != NSDecimalNumber.notANumber {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.currencyCode = currencyCode
guard let formattedStr = formatter.string(from: NSDecimalNumber(string: self)) else { return self }
return formattedStr
}
return self
}
来源:https://stackoverflow.com/questions/47447312/cant-get-uitextfield-to-populate-when-using-currency-format-of-numberformatter