How to restrict UITextField to take only numbers in Swift?

后端 未结 30 796
难免孤独
难免孤独 2020-12-04 08:40

I want the user to only enter numeric values in a UITextField. On iPhone we can show the numeric keyboard, but on iPad the user can switch to any keyboard.

相关标签:
30条回答
  • 2020-12-04 08:53

    Extend your view controller like this:

    class MyViewController: UIViewController, UITextFieldDelegate
    

    In the viewDidLoad function extend to your text field like this:

    myTextField.delegate = self
    

    And then use the following function:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let isNumber = CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: string))
        let withDecimal = (
            string == NumberFormatter().decimalSeparator &&
            textField.text?.contains(string) == false
        )
        return isNumber || withDecimal
    }
    

    This will now make sure the user can enter only decimal digits.

    Swift 4 + Accepts Number only and accepts one separator

    0 讨论(0)
  • 2020-12-04 08:53

    While most of these solutions will work, be aware that in some localisations a decimals are separated with a "," and not a "."

    The cleaner way to do this would be

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        let decimalCharacter = NSNumberFormatter().decimalSeparator
        let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet()
        characterSet.addCharactersInString(decimalCharacter)
    
        return replacementString.rangeOfCharacterFromSet(characterSet.invertedSet) == nil
    }
    
    0 讨论(0)
  • Here is my 2 Cents. (Tested on Swift 2 Only)

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    
      let aSet = NSCharacterSet(charactersInString:"0123456789").invertedSet
      let compSepByCharInSet = string.componentsSeparatedByCharactersInSet(aSet)
      let numberFiltered = compSepByCharInSet.joinWithSeparator("")
      return string == numberFiltered
    
    }
    

    This is just a little bit more strict. No decimal point either.

    Hope it helps :)

    PS: I assumed you looked after the delegate anyway.

    Update: Swift 3.0 :

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        let aSet = NSCharacterSet(charactersIn:"0123456789").inverted
        let compSepByCharInSet = string.components(separatedBy: aSet)
        let numberFiltered = compSepByCharInSet.joined(separator: "")
        return string == numberFiltered
    }
    
    0 讨论(0)
  • 2020-12-04 08:56

    Set KeyboardType Property :- Number Pad TextField Delegate please write below code

      func textField(_ textField: UITextField, shouldChangeCharactersIn 
      range: NSRange, replacementString string: String) -> Bool {
    
        if textField.text?.count == 0 && string == "0" {
            return false
        }
        return string == string.filter("0123456789".contains)
    }
    

    Number should not start from 0 and entered number +ve.

    0 讨论(0)
  • 2020-12-04 08:57

    As if there aren't enough answers, here's mine. I think every example allowed for decimal separators is flawed in either localization, backspaces, or copy/paste.

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        if string.isEmpty {return true} //allow for backspace
    
        let decimalSeparator = NSNumberFormatter().decimalSeparator ?? "."
        let validChars = NSMutableCharacterSet(charactersInString: decimalSeparator)
        validChars.formUnionWithCharacterSet(NSCharacterSet.decimalDigitCharacterSet())
    
        if validChars.isSupersetOfSet(NSCharacterSet(charactersInString: string)){
            switch string.componentsSeparatedByString(decimalSeparator).count-1 {
            case 0: //no decimals
                return true
    
            case 1: //if adding decimal, only allow if no existing decimal
                if let existingText = textField.text{
                    return existingText.componentsSeparatedByString(decimalSeparator).count <= 1
                }
                else {return true}
    
            default: //invalid decimals
                return false
            }
        }
    
        return false
    }
    
    0 讨论(0)
  • 2020-12-04 08:58

    In swift 4.1 and Xcode 9.4.1

    Add UITextFieldDelegate to your class

    class YourViewController: UIViewController, UITextFieldDelegate
    

    Then write this code in your viewDidLoad()

    mobileNoTF.delegate = self
    

    Write this textfield delegate function

    //MARK - UITextField Delegates
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        //For mobile numer validation
        if textField == mobileNoTF {
            let allowedCharacters = CharacterSet(charactersIn:"+0123456789 ")//Here change this characters based on your requirement
            let characterSet = CharacterSet(charactersIn: string)
            return allowedCharacters.isSuperset(of: characterSet)
        }
        return true
    }
    
    0 讨论(0)
提交回复
热议问题