How to restrict UITextField to take only numbers in Swift?

后端 未结 30 798
难免孤独
难免孤独 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 09:11

    Use number formatter

    Swift 4.x

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
          let s = NSString(string: textField.text ?? "").replacingCharacters(in: range, with: string)
          guard !s.isEmpty else { return true }
          let numberFormatter = NumberFormatter()
          numberFormatter.numberStyle = .none
          return numberFormatter.number(from: s)?.intValue != nil
     }
    
    0 讨论(0)
  • 2020-12-04 09:12

    Solution for swift 3.0 and above

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
      {
        let allowedCharacters = CharacterSet.decimalDigits
        let characterSet = CharacterSet(charactersIn: string)
        return allowedCharacters.isSuperset(of: characterSet)
      }
    
    0 讨论(0)
  • 2020-12-04 09:12

    This is a more readable version that will do "0-9" plus ".":

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    
        let existingTextHasDecimal = textField.text?.rangeOfString(".")
        let replacementTextHasDecimal = string.rangeOfString(".")
        let replacementTextAllCharacters = NSCharacterSet(charactersInString: string)
        let replacementTextOnlyDigits = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(replacementTextAllCharacters)
    
        if replacementTextHasDecimal != nil && existingTextHasDecimal != nil {
            return false
        }else{
            if replacementTextOnlyDigits == true {
                return true
            }else if replacementTextHasDecimal != nil{
                return true
            }else{
                return false
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-04 09:13

    I had actually done this when working through the Big Nerd Ranch book, my solution is:

    func textField(textField: UITextField, 
        shouldChangeCharactersInRange range: NSRange, 
        replacementString string: String) -> Bool {
    
        let newCharacters = NSCharacterSet(charactersInString: string)
        return NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newCharacters)
    }
    

    this only allows the numbers 0-9, to allow the "." as well is more complicated as you can only allow one "."

    0 讨论(0)
  • 2020-12-04 09:14

    I think you can force change the keyboard type by implementing UITextInputTraits protocol, optional var keyboardType

    //class ViewController: UIViewController, UITextInputTraits {
    
    @IBOutlet weak var textFieldKeyboardType: UITextField!{
        didSet{
            textFieldKeyboardType.keyboardType = UIKeyboardType.NumberPad
        }
    }
    var keyboardType: UIKeyboardType { 
        get{ 
            return textFieldKeyboardType.keyboardType
        } 
        set{ 
            if newValue != UIKeyboardType.NumberPad{
                self.keyboardType = UIKeyboardType.NumberPad
            }
        } 
    }
    
    0 讨论(0)
  • 2020-12-04 09:14

    I have edited Raj Joshi's version to allow one dot or one comma:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        let inverseSet = CharacterSet(charactersIn:"0123456789").inverted
        let components = string.components(separatedBy: inverseSet)
        let filtered = components.joined(separator: "")
    
        if filtered == string {
            return true
        } else {
            if string == "." || string == "," {
                let countDots = textField.text!.components(separatedBy:".").count - 1
                let countCommas = textField.text!.components(separatedBy:",").count - 1
    
                if countDots == 0 && countCommas == 0 {
                    return true
                } else {
                    return false
                }
            } else  {
                return false
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题