How can I declare that a text field can only contain an integer?

前端 未结 9 1880
星月不相逢
星月不相逢 2020-11-30 05:37

In swift, I am trying to make a text field that will allow a button to be enabled, but only when the text field contains an integer. How can I do this?

相关标签:
9条回答
  • 2020-11-30 06:14
    1. Make your view controller a UITextFieldDelegate by adding UITextFieldDelegate to the class declaration.
    2. Add IBOutlets for your text field and your button.
    3. In viewDidLoad set your button's isEnabled property to false and set self as the textField.delegate.
    4. Implement textField:shouldChangeCharactersInRange:replacementString: method. This method will be called every time your text field is edited. In there, check if the current text field converts to an Int by calling Int(text) and enable/disable your button as desired.

    Here is the code:

    class ViewController : UIViewController, UITextFieldDelegate {
    
        @IBOutlet weak var textField: UITextField!
        @IBOutlet weak var button: UIButton!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            button.isEnabled = false
            textField.delegate = self
            textField.keyboardType = .numberPad
        }
    
        func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
            // Find out what the text field will be after adding the current edit
            let text = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
    
            if Int(text) != nil {
                // Text field converted to an Int
                button.isEnabled = true
            } else {
                // Text field is not an Int
                button.isEnabled = false
            }
    
            // Return true so the text field will be changed
            return true
        }
    }
    
    0 讨论(0)
  • 2020-11-30 06:14

    As for accept backspace and other control characters I've used following method:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if string.isEmpty { // This is for accept control characters
            return true
        }
        let numericRegEx = "[0-9]"
        let predicate = NSPredicate(format:"SELF MATCHES %@", numericRegEx)
    
        let newText = (textFieldCount.text as! NSString).replacingCharacters(in: range, with: string)
    
        return predicate.evaluate(with: string)
    }
    

    If you want it to accept floating points also, just change RegEx to

    let numericRegEx = "[.0-9]"
    

    If limit text size to 10, change last row as following:

    return predicate.evaluate(with: string) && newText.count < 10
    
    0 讨论(0)
  • 2020-11-30 06:23

    IN SWIFT 4

            func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                 if textField == mobileTF{                   
                 let allowingChars = "0123456789"
                 let numberOnly = NSCharacterSet.init(charactersIn: allowingChars).inverted
                 let validString = string.rangeOfCharacter(from: numberOnly) == nil
                        return validString
                  }
             return true
             }
    
    0 讨论(0)
  • 2020-11-30 06:26

    Two things:

    1. Specify the keyboard type to only show the numeric keypad. So, set the keyboardType to .numberPad. This, however is not enough to stop the user from entering invalid characters in the text field. For example, the user is still able to paste text or switch keyboards when using an iPad.

    2. Specify the text field's delegate and implement shouldChangeCharactersInRange that will not accept any characters other than the digits 0 though 9:

      class ViewController: UIViewController, UITextFieldDelegate {
      
          @IBOutlet weak var textField: UITextField!
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              // you can set the following two properties for the text field in Interface Builder, if you'd prefer
      
              textField.delegate = self
              textField.keyboardType = .numberPad
          }
      
          func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
              let invalidCharacters = CharacterSet(charactersIn: "0123456789").inverted
              return string.rangeOfCharacter(from: invalidCharacters) == nil
          }
      
          // or, alternatively:
          //
          // func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
          //     return string.range(of: "^\\d*$", options: .regularExpression) != nil
          // }
      
      }
      

    For Swift 2 rendition, see previous revision of this answer.

    0 讨论(0)
  • 2020-11-30 06:27

    Here's a reusable method for Cocoa, swift 4.1

    1- Create a file with the class NSTextFieldFormated below

    2- In the 'Identity inspector' change the 'CustomClass class' of the field to be formatted to NSTextFieldFormated

    3- In the 'Attributes inspector' define the 'int Min Value', 'int Max Value' and 'int Length' of the field to be formatted

    4- Drag and drop an 'Object' (NSObject) from the 'Object library' to the 'View Controller Scene' in the outline interface builder objects listing (left of the interface drawing area)

    5- In the 'Identity inspector' set the 'CustomClass class' to NSTextFieldFormated

    6- Select the field to be formatted and in the Connections inspector set the field delegate to the new 'Text Field Formatted' object in 'View Controller Scene'.

    Then the NSTextField is now formatted.

    class NSTextFieldFormated: NSTextField, NSControlTextEditingDelegate {
    
        private struct Digit {
            var minValue: Int?      // minimum
            var maxValue: Int?      // maximum
            var digitAmt: Int?      // minimumIntegerDigits
        }
        private var digit = Digit()
    
        //-Integer
        @IBInspectable var intMinValue: Int {
            get {
                guard let minVal = digit.minValue else { return Int.min }
                return minVal
            }
            set { digit.minValue = newValue ; setFormatter() }
        }
        @IBInspectable var intMaxValue: Int {
            get {
                guard let maxVal = digit.maxValue else { return Int.max }
                return maxVal
            }
            set { digit.maxValue = newValue ; setFormatter() }
        }
        @IBInspectable var intLenght: Int {
            get {
                guard let length = digit.digitAmt else { return -1 }
                return length
            }
            set { digit.digitAmt = newValue ; setFormatter() }
        }
    
        private func setFormatter() {
            let lformatter = IntegerFormatter()
            lformatter.minimum = intMinValue as NSNumber
            lformatter.maximum = intMaxValue as NSNumber
            if intLenght != -1 {
                lformatter.minimumIntegerDigits = intLenght
            }
            self.formatter = lformatter
        }
    
        class IntegerFormatter: NumberFormatter {
            override func isPartialStringValid(_ partialString: String, 
                newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>?, 
                errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
    
                if partialString.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) != nil {
                    NSSound.beep()
                    return false
                }
    
                return Int(partialString) != nil
            }
        }
    
        override func controlTextDidChange(_ notification: Notification) {
            if let textField = notification.object as? NSTextFieldFormated {
                if let val = Int(textField.stringValue) {
                    //print(">4")
                    if val > textField.intMaxValue {
                        textField.stringValue = String(textField.intMaxValue)
                    }
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-30 06:31

    Swift 4: How about a simple guard and typecasting to Int as below

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
            guard let _ = Int(string) else {
                button.isEnabled = false
                return true
            }
                button.isEnabled = true
                return true
    }
    
    0 讨论(0)
提交回复
热议问题