【问题标题】:Allow only alphanumeric characters for a UITextFieldUITextField 只允许字母数字字符
【发布时间】:2011-11-24 09:40:03
【问题描述】:

如何在 iOS UITextField 中只允许输入字母数字字符?

【问题讨论】:

    标签: ios uitextfield uitextfielddelegate


    【解决方案1】:

    将 UITextFieldDelegate 方法 -textField:shouldChangeCharactersInRange:replacementString: 与 NSCharacterSet 一起使用,其中包含您要允许的字符的反转。例如:

    // in -init, -initWithNibName:bundle:, or similar
    NSCharacterSet *blockedCharacters = [[[NSCharacterSet alphanumericCharacterSet] invertedSet] retain];
    
    - (BOOL)textField:(UITextField *)field shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)characters
    {
        return ([characters rangeOfCharacterFromSet:blockedCharacters].location == NSNotFound);
    }
    
    // in -dealloc
    [blockedCharacters release];
    

    请注意,您需要声明您的类实现了协议(即@interface MyClass : SomeSuperclass <UITextFieldDelegate>)并将文本字段的delegate 设置为您的类的实例。

    【讨论】:

    • 你的意思是:返回 [characters rangeOfCharacterFromSet:blockedCharacters].location==NSNotFound;
    • 您倒置了字母数字字符集的任何特殊原因?您不能删除倒置集,然后将您的返回测试更改为!= NSNotFound?只是好奇,因为除了返回之外,我还有一些逻辑发生在里面
    • 是的——如果同时输入了多个字符(例如粘贴文本时),如果替换中存在 any 字母数字字符,则检查非反转集将允许更改文本,即使它们不是全部字母数字。
    【解决方案2】:

    Swift 3 版本

    目前接受的回答方式:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        // Get invalid characters
        let invalidChars = NSCharacterSet.alphanumerics.inverted
    
        // Attempt to find the range of invalid characters in the input string. This returns an optional.
        let range = string.rangeOfCharacter(from: invalidChars)
    
        if range != nil {
            // We have found an invalid character, don't allow the change
            return false
        } else {
            // No invalid character, allow the change
            return true
        }
    }
    

    另一种功能相同的方法:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        // Get invalid characters
        let invalidChars = NSCharacterSet.alphanumerics.inverted
    
        // Make new string with invalid characters trimmed
        let newString = string.trimmingCharacters(in: invalidChars)
    
        if newString.characters.count < string.characters.count {
            // If there are less characters than we started with after trimming
            // this means there was an invalid character in the input. 
            // Don't let the change go through
            return false
        } else {
            // Otherwise let the change go through
            return true
        }
    
    }
    

    【讨论】:

    • 如果用户粘贴不需要的字符,这将不起作用
    • @MarksCode 你是对的。我更新了该方法以使用粘贴的字符。我还添加了与接受的答案相同的方法。
    【解决方案3】:

    这就是我的做法:

    // Define some constants:
    #define ALPHA                   @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    #define NUMERIC                 @"1234567890"
    #define ALPHA_NUMERIC           ALPHA NUMERIC
    
    // Make sure you are the text fields 'delegate', then this will get called before text gets changed.
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    
        // This will be the character set of characters I do not want in my text field.  Then if the replacement string contains any of the characters, return NO so that the text does not change.
        NSCharacterSet *unacceptedInput = nil;
    
        // I have 4 types of textFields in my view, each one needs to deny a specific set of characters:
        if (textField == emailField) {
            //  Validating an email address doesnt work 100% yet, but I am working on it....  The rest work great!
            if ([[textField.text componentsSeparatedByString:@"@"] count] > 1) {
                unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:[ALPHA_NUMERIC stringByAppendingString:@".-"]] invertedSet];
            } else {
                unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:[ALPHA_NUMERIC stringByAppendingString:@".!#$%&'*+-/=?^_`{|}~@"]] invertedSet];
            }
        } else if (textField == phoneField) {
            unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:NUMERIC] invertedSet];
        } else if (textField == fNameField || textField == lNameField) {
            unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:ALPHA] invertedSet];
        } else {
            unacceptedInput = [[NSCharacterSet illegalCharacterSet] invertedSet];
        }
    
        // If there are any characters that I do not want in the text field, return NO.
        return ([[string componentsSeparatedByCharactersInSet:unacceptedInput] count] <= 1);
    }
    

    也请查看UITextFieldDelegate Reference

    【讨论】:

    • 这真的很有帮助。我唯一添加的是` if ( ( [string isEqualToString:@"@"] ) && (range.location == 0 ) ) { unacceptedInput = [NSCharacterSet characterSetWithCharactersInString:@"@"]; }` 在 emailField 分支中,以防止 @ 被用于启动电子邮件地址
    【解决方案4】:

    我找到了一个简单有效的答案并想分享:

    将 EditingChanged 事件的 UITextField 连接到以下 IBAction

    -(IBAction) editingChanged:(UITextField*)sender
    {    
        if (sender == yourTextField)
        {
            // allow only alphanumeric chars
            NSString* newStr = [sender.text stringByTrimmingCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]];
    
            if ([newStr length] < [sender.text length])
            {
                sender.text = newStr;
            }
        }
    }
    

    【讨论】:

    • 一个问题 - 比较长度比只比较内容更好吗?除非长度实际上存储在 NSString 对象中,否则我会想象无论哪种方式,比较都会花费m + n 时间,其中mnewStr 的长度,nsender.text 的长度。跨度>
    【解决方案5】:

    Swift 中的 RegEx 方式:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
         if string.isEmpty {
             return true
         }
         let alphaNumericRegEx = "[a-zA-Z0-9]"
         let predicate = NSPredicate(format:"SELF MATCHES %@", alphaNumericRegEx)
         return predicate.evaluate(with: string)
    }
    

    【讨论】:

    • 要支持复制粘贴,请使用此正则表达式:“[a-zA-Z0-9]+”。
    【解决方案6】:

    对于斯威夫特: 将事件 EditingChanged 的​​ UITextField 连接到以下 IBAction:

    @IBAction func ActionChangeTextPassport(sender:UITextField){
        if sender == txtPassportNum{
            let newStr = sender.text?.stringByTrimmingCharactersInSet(NSCharacterSet.alphanumericCharacterSet().invertedSet)
            if newStr?.characters.count < sender.text?.characters.count{
                sender.text = newStr
            }
        }
    }
    

    【讨论】:

      【解决方案7】:

      您必须使用textField delegate 方法,并使用textFieldDidBeginEditingshouldChangeCharactersInRangetextFieldDidEndEditing 方法来检查字符。

      请参阅this link 获取文档。

      【讨论】:

        猜你喜欢
        • 2014-04-11
        • 1970-01-01
        • 1970-01-01
        • 2012-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多