数字格式化程序不允许显示小数

Number formatter not allowing decimals to show

这是强制性的 "I'm new to programming" 但是,我搜索了所有可用的答案并得出结论,我的问题 可能 比代码更逻辑相关,但我可以也错了。我正在构建一个计算器应用程序,除显示中的 numberFormatter(显示逗号分隔符)外,一切正常。每当我尝试格式化显示中的数字时,我无法让显示显示小数点和逗号。

如果我以小数 .1234 开头,我得到 0.1234,如果我输入 12345,我得到 12,345,但如果我输入 12345.678,我得到 12,345。我失去了小数点。我已经测试了它和我删除无关的“。”的功能。似乎不是问题。如果我 运行 标签格式控件之外的字符串扩展名 numberFormatter 它似乎可以工作,但我需要防止出现多个小数点和无关的“0”。

我正在向 IBAction 显示代码,其中包含显示标签上显示的按钮,display.text 这就是问题所在。此后的所有计算都运行良好,使用 replacingOccurrences(of: ",", with: "") 创建一个干净的字符串以转换为 Double 并进行计算。

我正在使用 sting 扩展来进行格式化。几个星期以来,我一直在断断续续地研究这个问题。有任何想法吗?我是否必须重构在 label.text 中输入文本的方式?

这里是向 UILabel display 添加文本的代码。

@IBAction func btnTouchDigit(_ sender: UIButton) {

        let digit = sender.currentTitle!

        if isUserTyping {
            var formattedNumber = ""

            print( "is user typting + String\(isUserTyping)")

            // make sure we aren't adding a second period

            var textCurrentlyInDisplay = display.text
            textCurrentlyInDisplay = textCurrentlyInDisplay?.replacingOccurrences(of: ",", with: "")

            if digit == "." && ((textCurrentlyInDisplay?.range(of: ".")) != nil) {
                return
            }
            else {
                formattedNumber = (textCurrentlyInDisplay! + digit)
                print("formattedNumber = \(formattedNumber.twoFractionDigits)")
                display.text = formattedNumber.twoFractionDigits

                // put code here to format label.text to show thousand seperators
                print("textCurrentlyInDisplay end = \(textCurrentlyInDisplay!)")     
            }
        }

          // make sure we aren't entering a bunch of zero's        
        else { print("else + \(isUserTyping)")

            display.text = digit
            if digit == "0" {return}
            else if digit == "." {display.text = "0."}
            // display.text = (digit == "." ? "0" : "") + digit
            isUserTyping = true
        }

    }

这是我的扩展,用于处理 numberFormatter 的字符串转换。

extension String {
    var twoFractionDigits: String {
        let styler = NumberFormatter()
        styler.minimumFractionDigits = 0
       styler.maximumFractionDigits = 16
       styler.numberStyle = .decimal
        let converter = NumberFormatter()
        converter.decimalSeparator = "."
        if let result = converter.number(from: self) {
            return styler.string(from: result)!
        }
        return ""

    }

我找到了解决我的问题的技巧。它不漂亮,但它有效。我能够让 numberFormatter 更新并显示小数点后的数字,但这导致了一个新问题。如果您键入 12345.00,您将得到 12,344,并且在您按下另一个数字之前看不到尾随的 0。例如 12345.1 -> 12,345.1、12345.001 -> 12,345.001,但 12345.00 -> 12,345。

我需要它动态工作,以便用户知道输入了多少个零。我的技巧是将最终金额分成两个数组。一种是预先格式化的,另一种是 post 格式化的。然后将两者结合在一起以获得最终的显示数字。

如果有人有任何想法,我仍然很想找到更有效的解决方案。

这是更新后的代码。

@IBAction func btnTouchDigit(_ sender: UIButton) { 让数字 = sender.currentTitle!

    if isUserTyping {
        preFormattedNumber = (display.text?.replacingOccurrences(of: ",", with: ""))!

        // set the limit for number of digits user can enter at once
        if display.text!.count >= 16 {
            return
        }

        else {
            // make sure we aren't adding a second period
            if digit == "." && ((preFormattedNumber.range(of: ".")) != nil) {

                print("extra decimal pressed")
                return
            }
            else {
                preFormattedNumber = (preFormattedNumber + digit)
                print("preFormattedNumber before Formatting = \(preFormattedNumber)")
            }

            // put code here to format label.text to show thousand seperators
            if ((preFormattedNumber.range(of: ".")) != nil){
                print("just checked for .")
                let numPreFormat = preFormattedNumber
                let numAfterFormat = preFormattedNumber.twoFractionDigits
                let numArray = numPreFormat.components(separatedBy: ".")
                let numArrayFormatted = numAfterFormat.components(separatedBy: ".")
                let afterDecimal = numArray.last
                let beforeDecimal = numArrayFormatted.first
                let finalNumberToDisplay = beforeDecimal! + "." + afterDecimal!
                print("numArray = \(numArray)")
                print("final number to display = \(finalNumberToDisplay)")
                print("numArray = \(numArray)")
                display.text = finalNumberToDisplay
                runningNumber = display.text!
            }
            else {
                display.text = preFormattedNumber.twoFractionDigits
                runningNumber = display.text!
            }
        }
    }

        // make sure we aren't entering a bunch of zero's
    else { print("else + \(isUserTyping)")
        preFormattedNumber = digit
        display.text = preFormattedNumber
        runningNumber = display.text!
        if digit == "0" {return}
        else if digit == "." { preFormattedNumber = "0.";
        }

        display.text = preFormattedNumber
        runningNumber = display.text!
        isUserTyping = true
    }


}