How to limit the textfield entry to 2 decimal places in swift 4?

后端 未结 8 1755
逝去的感伤
逝去的感伤 2021-01-02 00:12

I have a textfield and I want to limit the entry to max 2 decimal places.

number like 12.34 is allowed but not 12.345

How do I do it?

相关标签:
8条回答
  • 2021-01-02 00:30

    Set your controller as the delegate for the text field and check if the proposed string satisfy your requirements:

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
        textField.keyboardType = .decimalPad
    }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let oldText = textField.text, let r = Range(range, in: oldText) else {
            return true
        }
    
        let newText = oldText.replacingCharacters(in: r, with: string)
        let isNumeric = newText.isEmpty || (Double(newText) != nil)
        let numberOfDots = newText.components(separatedBy: ".").count - 1
    
        let numberOfDecimalDigits: Int
        if let dotIndex = newText.index(of: ".") {
            numberOfDecimalDigits = newText.distance(from: dotIndex, to: newText.endIndex) - 1
        } else {
            numberOfDecimalDigits = 0
        }
    
        return isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 2
    }
    
    0 讨论(0)
  • 2021-01-02 00:31
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                let dotString = "."
    
                if let text = textField.text {
                    let isDeleteKey = string.isEmpty
    
                    if !isDeleteKey {
                        if text.contains(dotString) {
                            if text.components(separatedBy: dotString)[1].count == 2 {
    
                                        return false
    
                            }
    
                        }
    
                    }
                }
                return true
             }
    
    0 讨论(0)
  • 2021-01-02 00:35

    Following the Code Different's answer, I've improved the code to support a different Locale and different UITextFields in the same class.

      func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard textField.keyboardType == .decimalPad, let oldText = textField.text, let r = Range(range, in: oldText) else {
            return true
        }
    
        let newText = oldText.replacingCharacters(in: r, with: string)
        let isNumeric = newText.isEmpty || (Double(newText) != nil)
    
        let formatter = NumberFormatter()
        formatter.locale = Locale.current
        let decimalPoint = formatter.decimalSeparator ?? "."
        let numberOfDots = newText.components(separatedBy: decimalPoint).count - 1
    
        let numberOfDecimalDigits: Int
        if let dotIndex = newText.index(of: ".") {
            numberOfDecimalDigits = newText.distance(from: dotIndex, to: newText.endIndex) - 1
        } else {
            numberOfDecimalDigits = 0
        }
        return isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 2
      }
    
    0 讨论(0)
  • 2021-01-02 00:39

    Guys, here's the solution:

     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            let dotString = "."
    
            if let text = textField.text {
                let isDeleteKey = string.isEmpty
    
                if !isDeleteKey {
                    if text.contains(dotString) {
                        if text.components(separatedBy: dotString)[1].count == 2 {
    
                                    return false
    
                        }
    
                    }
    
                }
            }
      }
    
    0 讨论(0)
  • 2021-01-02 00:41

    Swift 5. Adding to Enrique's answer (based on Code Different baseline), I found the need to allow the Delete key to operate anywhere on the line along with a sign (+ or -) or decimal point at the beginning of the input line.

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // Limit number fields to +/- Real #s: sign as first character, one decimal separator, one decimal place after separator
        if string.isEmpty { return true }   // Allow delete key anywhere!
        guard let oldText = textField.text, let rng = Range(range, in: oldText) else {
            return true
        }
        let newText = oldText.replacingCharacters(in: rng, with: string)
    
        let isNumeric = newText.isEmpty || (Double(newText) != nil)
    
        let formatter = NumberFormatter()
        formatter.locale = .current
        let decimalPoint = formatter.decimalSeparator ?? "."
        let numberOfDots = newText.components(separatedBy: decimalPoint).count - 1
    
        let numberOfDecimalDigits: Int
        if let dotIndex = newText.firstIndex(of: ".") {
            numberOfDecimalDigits = newText.distance(from: dotIndex, to: newText.endIndex) - 1
        } else {
            numberOfDecimalDigits = 0
        }
        if newText.count == 1 && !isNumeric {   // Allow first character to be a sign or decimal point
            return CharacterSet(charactersIn: "+-" + decimalPoint).isSuperset(of: CharacterSet(charactersIn: string))
        }
        return isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 1
    }
    
    0 讨论(0)
  • 2021-01-02 00:44

    Only Two decimal point allow and only one "." allow

     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
                        let text: NSString = textField.text! as NSString
                        let resultString = text.replacingCharacters(in: range, with: string)
    
    
            //Check the specific textField 
             if textField == costTextField {
                 let textArray = resultString.components(separatedBy: ".")
                 if textArray.count > 2 { //Allow only one "."
                    return false
                 }
               if textArray.count == 2 {
                  let lastString = textArray.last
                 if lastString!.count > 2 { //Check number of decimal places 
                       return false
                   }
                }
              }
               return true
           }
    
    0 讨论(0)
提交回复
热议问题