1

I am using Xcode 14 Swift 5 and I am new to it. I am trying to make the textField accpet maximum 3 digits but also can have a decimal number in it with 2 digits. (E.g. the user can enter 123 or 123.45 but not 12345 nor 12134.54)

Thanks in advance.

here is my code to restrict the textField to accept max 3 digits but I can't write the rest.

    // TextField Config
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        
        guard let text = textField.text else { return true }
        
        let text_Length = text.count + string.count - range.length
        if text_Length > 3 {
            return false
        }
        
        return true
    }
    // Done

1 Answers1

0

Regular expressions are often the quick-and-dirty to solution for this sort of stuff:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let original = textField.text ?? ""
    guard let range = Range(range, in: original) else { return true }

    let result = original.replacingCharacters(in: range, with: string)
    let match = result.range(of: #"^\s*[0-9]{0,3}(\.[0-9]{0,2})?\s*$"#, options: .regularExpression)

    // in Swift 5.7, you might use Regex
    //
    // let match = result.wholeMatch(of: /\s*[0-9]{0,3}(\.[0-9]{0,2})?\s*/)

    return match != nil
}

The regex is matching zero to three digits, optionally follows by a period and an additional zero to two digits, and ignores whitespace.

Note, this will permit the entry of a value of “.5”, for example, without the leading zero. So, when converting to a numeric value, you might want to either add the leading zero (either during entry or when converting to a numeric value) or have the regex require at least one digit before the .:

let match = result.wholeMatch(of: /\s*[0-9]{0,2}([0-9]\.[0-9]{0,2})?\s*/)

Personally, I think it is better to let the user enter .5 and clean it up at the end, adding a leading 0 to make it 0.5, when parsing the text field input. But, you can do whatever you like.

Rob
  • 415,655
  • 72
  • 787
  • 1,044