如何声明文本字段只能包含整数?

时间:2014-11-13 22:41:45

标签: text swift int uitextfield textfield

在swift中,我试图创建一个允许按钮启用的文本字段,但仅当文本字段包含整数时。我怎么能这样做?

9 个答案:

答案 0 :(得分:55)

两件事:

  1. 指定键盘类型以仅显示数字小键盘。因此,请将keyboardType设置为.numberPad。但这不足以阻止用户在文本字段中输入无效字符。例如,用户在使用iPad时仍然可以粘贴文本或切换键盘。

  2. 指定文本字段的委托并实施shouldChangeCharactersInRange,但不会接受0以外的任何字符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
        // }
    
    }
    
  3. 对于Swift 2的演绎,请参阅此答案的上一版本。

答案 1 :(得分:15)

  1. 通过将UITextFieldDelegate添加到类声明中,使视图控制器成为UITextFieldDelegate
  2. 为您的文字字段和按钮添加IBOutlet
  3. viewDidLoad中,将按钮的isEnabled媒体资源设为false,并将self设为textField.delegate
  4. 实施textField:shouldChangeCharactersInRange:replacementString:方法。每次编辑文本字段时都会调用此方法。在那里,通过调用Int检查当前文本字段是否转换为toInt(),并根据需要启用/禁用您的按钮。
  5. 以下是代码:

    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
        }
    
        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 let intVal = text.toInt() {
                // 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
        }
    }
    

    编辑:在Swift 3中,enabled属性更改为isEnabled

答案 2 :(得分:4)

迅速4:如下所示,简单的guardtypecasting to Int怎么样

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
}

答案 3 :(得分:2)

  

首先,您必须自己继承UITextViewDelegate类   课

class ViewController: UIViewController, UITextViewDelegate {
  

第二次添加IBOutlet

@IBOutlet weak var firstName: UITextField!
  

第三个必须确保该对象正在使用

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



      }
  }

答案 4 :(得分:1)

每个文字字段都有一个keyboardType。您可以将其设置为UIKeyboardType.NumbersAndPunctuation以仅显示数字,并且仍然存在返回键(防御性UI)。然后,您可以使用NSScanner的{​​{1}}来检查textField.text是否为有效整数。

答案 5 :(得分:0)

您可以使用NSScanner执行此操作,尝试使用此功能可能很有用,如果有任何问题,请告诉我

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" );

浏览链接http://rosettacode.org/wiki/Determine_if_a_string_is_numeric#Objective-C。在swift中尝试它,类和方法名称是相同的。

答案 6 :(得分:0)

这是可可的可重用方法,迅速4.1

1-使用下面的类 NSTextFieldFormated 创建文件

2-在“ 身份检查器”中,将要设置格式的字段的“ CustomClass类”更改为 NSTextFieldFormated

3-在“ 属性检查器”中,定义“ 整数最小值”,“ 整数最大值”和“ int要格式化的字段的长度

4-将“对象”(NSObject)从“ 对象库”拖放到大纲界面构建器对象列表中的“ View Controller Scene ”中(界面绘图区域的左侧)

5-在“ 身份检查器”中,将“ CustomClass类”设置为 NSTextFieldFormated

6-选择要设置格式的字段,然后在“连接”检查器中将字段委托设置为“ View Controller Scene ”中新的“ Text Field Formatted ”对象。

然后 NSTextField现在已格式化

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

答案 7 :(得分:0)

对于接受退格和其他控制字符,我使用了以下方法:

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

如果您希望它也接受浮点,只需将RegEx更改为

let numericRegEx = "[.0-9]"

如果将文字大小限制为10,请按如下所示更改最后一行:

return predicate.evaluate(with: string) && newText.count < 10

答案 8 :(得分:0)

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