Can't get UITextField to populate when using .currency format of NumberFormatter()

牧云@^-^@ 提交于 2019-12-13 02:59:11

问题


I borrowed and modified some code from SO to solve a problem where I was trying to format text that I inputted into my UITextFields. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!