UITextField - 防止用户输入非标准字符(如表情符号)

jhi*_*t00 3 uitextfield uikeyboard nscharacterset ios

我的应用程序创建并存储EKEvents到标准日历数据库中,但是,我发现如果我使用表情符号作为事件的"注释",则在尝试从日历中读取事件时会导致崩溃.

不想不需要使用表情符号event.notes.我碰巧正在测试,当它让我保存活动时有点震惊.(表情符号甚至出现在日历中)

所以我认为我的问题可以通过2种方式解决,这两种方式都是我无法弄清楚的.

1)我可以禁用或隐藏自定义键盘按钮吗?< - 我更喜欢这个解决方案

在此输入图像描述

2)如果没有,我如何创建一个包含所有标准键盘中所有可能字符的字符集,以确保用户不键入表情符号时进行检查?

我尝试使用一些标准字符集来检查,比如说alphanumericCharacterSet,但是使用它,我不能输入空格.

这是我到目前为止使用的代码,用于检查用户输入的字符:

- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (string.length == 0) {
        return YES;
    }

    NSCharacterSet *myCharSet = [NSCharacterSet alphanumericCharacterSet];
    for (int i = 0; i < [string length]; i++) {
        unichar c = [string characterAtIndex:i];
        if ([myCharSet characterIsMember:c]) {
            return YES;
        }
    }

    UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Invalid Input" message:@"Oops! You can't use that character." delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
    [av show];
    return NO;
}
Run Code Online (Sandbox Code Playgroud)

编辑:澄清错误

没有错误,只有崩溃.我的应用程序保存日历事件,并将其显示在列表中给用户.然后,用户可以将事件标记为"付费"或"未付费",此时我将字符串附加到.notes事件" - 付费" 的属性.当我重新加载表时,如果事件已付款,则会向用户显示特定图标.当保存甚至有一个表情符号作为.notes属性时发生崩溃,我尝试追加.notes.

Tim*_*Tim 6

您可以NSCharacterSet使用union来组合s以添加更多允许的字符:

    NSMutableCharacterSet *myCharSet = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];
    [myCharSet formUnionWithCharacterSet:[NSCharacterSet whitespaceAndNewlineCharacterSet];
Run Code Online (Sandbox Code Playgroud)

以下是可供选择的字符集列表:

controlCharacterSet
whitespaceCharacterSet
whitespaceAndNewlineCharacterSet
decimalDigitCharacterSet
letterCharacterSet
lowercaseLetterCharacterSet
uppercaseLetterCharacterSet
nonBaseCharacterSet
alphanumericCharacterSet
decomposableCharacterSet
illegalCharacterSet
punctuationCharacterSet
capitalizedLetterCharacterSet
symbolCharacterSet
newlineCharacterSet
Run Code Online (Sandbox Code Playgroud)

此外,您的代码正在检查以确保任何字符不在集合之外; 我认为你的目的是检查所有字符都不在集合之外.(这仅适用于用户同时输入多个字符的情况 - 请考虑复制和粘贴).

考虑调整你的循环看起来更像这样:

NSCharacterSet *myCharSet = [NSCharacterSet alphanumericCharacterSet];
for (int i = 0; i < [string length]; i++) {
    unichar c = [string characterAtIndex:i];
    if ([myCharSet characterIsMember:c] == NO) {
        // add your user alert here
        return NO;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样你的循环就不会简单地退出它找到的第一个好角色; 相反,它将退出第一个坏角色.

  • 只使用`-rangeOfCharacterFromSet:`比自己迭代`unichar'更容易. (2认同)