chickenparm chickenparm - 1 year ago 152
iOS Question

Limit Text Field to one decimal point input, numbers only, and two characters after the decimal place - Swift 3

I am struggling to do this with Swift 3. I have a text field that I would like to limit to only numbers and one decimal point and two characters after the decimal place. I would also like to have it work in regions where a decimal point is not used when entering non-integers. Thank you for any suggestions!

Answer Source

You need to assign delegate to your textfield and in the shouldChangeCharactersIn delegate method do your validations:

  1. Add extension with validation methods for the string:

    extension String{
        private static let decimalFormatter:NumberFormatter = {
            let formatter = NumberFormatter()
            formatter.allowsFloats = true
            return formatter
        private var decimalSeparator:String{
            return String.decimalFormatter.decimalSeparator ?? "."
        func isValidDecimal(maximumFractionDigits:Int)->Bool{
            // Depends on you if you consider empty string as valid number
            guard self.isEmpty == false else {
                return true
            // Check if valid decimal
            if let _ = String.decimalFormatter.number(from: self){
                // Get fraction digits part using separator
                let numberComponents = self.components(separatedBy: decimalSeparator)
                let fractionDigits = numberComponents.count == 2 ? numberComponents.last ?? "" : ""
                return fractionDigits.characters.count <= maximumFractionDigits
            return false
  2. In your delegate method:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // Get text
        let currentText = textField.text ?? ""
        let replacementText = (currentText as NSString).replacingCharacters(in: range, with: string)
        // Validate
        return replacementText.isValidDecimal(maximumFractionDigits: 2)