如何将 UITextField 限制为一组定义的字符并限制长度?

How to restrict UITextField to a defined set of characters and limit the length?

我正在开发登录和注册视图控制器。我使用 :

将用户名限制为 12 个字符,将密码限制为 16 个字符
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range   replacementString:(NSString *)string
{

  if(textField==self.userField){

      NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
      return !([newString length] > 12);
    }

    else if(textField==self.passwordField){
        NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
        return !([newString length] > 16);

    }

    return YES;

}

这很好用,但我也想将它限制为一组字符以阻止不需要的符号和中文字符。我想定义这个集合:

#define ACCEPTABLE_CHARACTERS @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

不确定如何将它添加到上述方法中并使两者都起作用。如果我只检查字符集而不检查长度,代码将是:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string  {
    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet];

    NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];

    return [string isEqualToString:filtered];
}

但不确定如何组合它们。有人能帮助我吗?谢谢!

为什么不使用正则表达式来匹配这些字符?

你可以这样做(我将它划分为功能以提高可读性和易于扩展条件)

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    return ([self checkLengthOfString:newString inField:textField] && [self checkCharacter:newString]);
}


// Check Length
- (BOOL)checkLengthOfString:(NSString *)text inField:(UITextField *)textField
{
   if(textField == self.userField)
   {
      return !([text length] > 12);
   }
   else if(textField == self.passwordField)
   {
      return !([text length] > 16);
   }
}

// Check character
- (BOOL)checkCharacter:(NSString *)text
{
    BOOL status        = YES;
    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet];
    NSRange r          = [text rangeOfCharacterFromSet:s];
    if (r.location != NSNotFound)
    {
       status = NO;
    }
    return status;
}

我知道这已经得到解答,但我遇到了类似的情况,我发现 Whosebug 上的 none 个答案处理了退格字符。

我需要将 UITextField 的输入限制为特定数量的字母数字字符,但能够输入空格。

此外,使用 [textField length] > kMAXNUMCHARS 导致了一个问题:一旦达到最大字符数,您将无法退格。

这是我的完整解决方案。它还不允许前导空格。保存值时(在我的例子中是 PLIST 文件)

在我的 Constants.h 文件中,我定义了:

#define ALLOWED_CHARECTERS @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
extern const int kMAXUSERNAMELENGTH;

然后在 Constants.m:

const int kMAXUSERNAMELENGTH = 9;

我将 class 定义为带有行

的 UITextFieldDelegate
[self._txtUsername.textField  setDelegate:self];

不要忘记在您的 class 定义中声明 UITextFieldDelegate 协议

@interface MyClass : CCNode <UITextFieldDelegate>

最后,

    //UITextFiledDelegate Protocol method
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

        //disallow leading spaces. must allow trailing spaces- never know if we'll add another char
        //we trim trailing spaces when we save the TextField value, in our case to  Plist file
        if (range.location == 0 && [string isEqualToString:@" "]) 
            return NO;

        //we use defined ALLOWED_CHARECTERS so we can add chars later, easily. 
        //we could use [NSCharacterSet alphanumericCharacterSet] if we don't need to allow spaces
        NSCharacterSet *allowedInput = [NSCharacterSet characterSetWithCharactersInString:ALLOWED_CHARECTERS];
        NSArray* arChar = [string componentsSeparatedByCharactersInSet:allowedInput]; //arChar.count = 1 if 'allowedInput' not in 'string'

        //disallow input if its not a backspace (replacementString paramater string equal @"" if a backspace) AND
        //(disallow input >= kMAXUSERNAMELENGTH chars, OR disallow if not in allowed allowedChar set
        if ( ![string isEqual:@""]  && (  [textField.text length] >= kMAXUSERNAMELENGTH || !([arChar count] > 1)) ) 
             return NO;

        return YES;

    }

我希望这对某人有所帮助。