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

隐身守侯 提交于 2019-11-26 13:57: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?


回答1:


  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
    }
}



回答2:


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.




回答3:


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
}



回答4:


1st you have to inherit the UITextViewDelegate class with you own class

class ViewController: UIViewController, UITextViewDelegate {

2nd add an IBOutlet

@IBOutlet weak var firstName: UITextField!

3rd you have to assure this object is using

override func viewDidLoad() {
        super.viewDidLoad()
   firstName.delegate = self
}


func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if textField == firstName {
                let allowedCharacters = "1234567890"
                let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
                let typedCharacterSet = CharacterSet(charactersIn: string)
                let alphabet = allowedCharacterSet.isSuperset(of: typedCharacterSet)
              return alphabet



      }
  }



回答5:


Each text field has a keyboardType. You could set this to UIKeyboardType.NumbersAndPunctuation to only show numbers and still have the return key present (defensive UI). You could then use NSScanner's scanInt() to check if textField.text is a valid integer.




回答6:


You can use NSScanner to do that here is the which might be useful trying using this and let me know if there are any issues

if( [[NSScanner scannerWithString:@"-123.4e5"] scanFloat:NULL] )
    NSLog( @"\"-123.4e5\" is numeric" );
else
    NSLog( @"\"-123.4e5\" is not numeric" );

if( [[NSScanner scannerWithString:@"Not a number"] scanFloat:NULL] )
    NSLog( @"\"Not a number\" is numeric" );
else
    NSLog( @"\"Not a number\" is not numeric" );

go through the link http://rosettacode.org/wiki/Determine_if_a_string_is_numeric#Objective-C. Try it in swift the class and method names are same.




回答7:


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)
                }
            }
        }
    }
}



回答8:


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



回答9:


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
         }


来源:https://stackoverflow.com/questions/26919854/how-can-i-declare-that-a-text-field-can-only-contain-an-integer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!