【问题标题】:Can't get UITextField to populate when using .currency format of NumberFormatter()使用 NumberFormatter() 的 .currency 格式时无法填充 UITextField
【发布时间】:2017-11-23 03:56:47
【问题描述】:

我从 SO 借用并修改了一些代码,以解决我试图格式化输入到 UITextFields 中的文本的问题。如果我使用.decimal numberStyleNumberFormatter 它可以工作(在我需要的地方添加一个逗号)但是如果我使用.currency 我一旦运行应用程序就无法输入任何内容。 UITextField 不会填充。

我尝试过使用语言环境,但这似乎没有解决任何问题。

我要做的就是在用户开始输入UITextField 时立即在他们输入的数字前面显示“$”符号

不管有没有我正在使用的 digitsOnly 扩展,它都在这样做,所以这似乎不是造成它的原因。

相关代码:

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: "")
        }
    }

【问题讨论】:

    标签: ios swift uitextfield nsnumberformatter


    【解决方案1】:

    在您的文本字段委托中试试这个。

    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 != "")
        }
    }
    

    【讨论】:

    • string 没有 .count 方法,因为它不是数组。
    • 啊,知道了,改为.characters.count。与dropLast 方法相同。我现在有点工作。当我达到 100% 时会更新。谢谢。
    • 对我的特定switch 语句进行了一些修改。谢谢!!
    • 一些观察。首先,假设用户输入了15,并注意到他们打算输入25,所以他们突出显示1并按下2。您想用2 替换1,而不仅仅是将2 添加到末尾(导致152)。其次,我建议使用Decimal 而不是NSDecimalNumber。第三,如果你要用另一个字符串替换字符串,你真的会想知道当前UITextPosition在新字符串中的位置,并相应地更新position
    【解决方案2】:

    在您的扩展程序中尝试此代码并将其与您的newString 和货币代码(例如USD)一起使用,最好是与number with decimal 键盘一起使用,这样您就不需要事先检查格式

    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
        }
    

    【讨论】:

    • 我会直接在newString 声明的末尾运行它吗?因为当我尝试时,我根本无法输入UITextField。如果我用formattedString?.toCurrencyFormatter(with: "USD") 分配textField.text 属性,则第一个数字将显示为正确格式(即4 显示为4.00 美元),但如果我在键盘上按另一个数字,它会将字段清零。
    猜你喜欢
    • 2012-09-02
    • 2017-01-20
    • 1970-01-01
    • 2018-05-13
    • 1970-01-01
    • 2013-10-18
    • 2011-07-07
    • 2011-04-13
    • 2018-09-29
    相关资源
    最近更新 更多