2017-08-26 74 views
0

这里是强制性的“我是编程新手”,但是,我搜索了所有可用的答案,并得出结论认为我的问题可能是比代码更多的逻辑关系,但我可以对此也是错误的。我正在构建一个计算器应用程序,除了显示屏中的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 "" 

    } 
+0

有你'twoFractionDigits'方法没有问题。按照预期,在“1234.56”结果中输入“1,234.56”。所以你的问题在别处。使用你的调试器,看看你输入'1234.'后会发生什么,然后点击'5'。 – rmaddy

+0

我在btnTouchDigit函数的最后放置了一个断点,并用12345.111逐步完成,仍然得到12,345,111。没有错误,也没有小数。 –

回答

0

我发现了一个黑客来解决我的问题。这并不漂亮,但它的工作原理。我能够让numberFormatter更新并显示小数点后的数字,但这导致了一个新问题。如果你输入12345.00,你会得到12,344,直到你按下另一个数字时才看到尾部0。 ex 12345.1→12,345.1,12345.001→12,345.001,但是12345.00→> 12,345。

我需要它动态工作,以便用户知道输入了多少个零。我的破解是把最后的数量分成两个数组。一个预格式化和一个后格式化。然后将两者一起加入最终显示编号。

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

这里是更新的代码。

@IBAction func btnTouchDigit(_ sender:UIButton){ let digit = 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 
    } 


}