Question

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if([string isEqualToString:@" "] || [string isEqualToString:@"@"] || [string isEqualToString:@"!"] || [string isEqualToString:@"#"] || [string isEqualToString:@"$"] || [string isEqualToString:@"%"] || [string isEqualToString:@"^"] || [string isEqualToString:@"&"] || [string isEqualToString:@"*"] || [string isEqualToString:@"("] || [string isEqualToString:@")"] || [string isEqualToString:@"+"] || [string isEqualToString:@"-"])
        return NO;
    return YES;
}

I am using this method to restrict all these characters. It works fine when user types text from keyboard. If user paste text or use siri to enter text nothing happens.

How to fix it.

Was it helpful?

Solution 2

Try to customize your delegate method like this:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if([string isEqualToString:@" "] || [string isEqualToString:@"@"] || [string isEqualToString:@"!"] || [string isEqualToString:@"#"] || [string isEqualToString:@"$"] || [string isEqualToString:@"%"] || [string isEqualToString:@"^"] || [string isEqualToString:@"&"] || [string isEqualToString:@"*"] || [string isEqualToString:@"("] || [string isEqualToString:@")"] || [string isEqualToString:@"+"] || [string isEqualToString:@"-"])
    {
        return NO;
    }
    else if([string length] > 1)
    {
        NSCharacterSet *notAllowedChars = [NSCharacterSet characterSetWithCharactersInString:@"@!!#$%^&*()+-@%"];
        NSString *resultString = [[string componentsSeparatedByCharactersInSet:notAllowedChars] componentsJoinedByString:@""];
        textField.text = resultString;
        return NO;
    }
    return YES;
}

OTHER TIPS

When you enter text through keyboard, shouldChangeCharactersInRange gives you single characters in string parameter for every entry. When you paste it or enter through siri, it gives you whole string or words that have been added. In your case, you are comparing string as a single character which fails in paste and siri case.. I have written code snippet for you. Try it and tell me whether it works or not. It basically removes special characters from string.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if([string length] > 0)
    {
         NSCharacterSet *notAllowedChars = [NSCharacterSet characterSetWithCharactersInString:@"~!@#$%^&*(){}_+:\"<>?,./;'[]-="];
         NSString *resultString = [[string componentsSeparatedByCharactersInSet:notAllowedChars] componentsJoinedByString:@""];
         textField.text = [NSString stringWithFormat:@"%@%@", textField.text, resultString];
         return NO;
    }
    return YES;
}

#define Alpha_Numeric @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string  {

        NSCharacterSet *charSet = [[NSCharacterSet characterSetWithCharactersInString:Alpha_Numeric] invertedSet];

        NSString *resStr = [[string componentsSeparatedByCharactersInSet:charSet] componentsJoinedByString:@""];

        return [string isEqualToString:resStr];
    }

You current code only checks for equality with single character. Paste string can contain more than one character. You can do filtering of strings with character set:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSCharacterSet *invalidCharacters = [NSCharacterSet characterSetWithCharactersInString:@" @!#$%%^&*()+-"];
    if ([string rangeOfCharacterFromSet:invalidCharacters].location != NSNotFound) {
        NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
        textField.text = [[newText componentsSeparatedByCharactersInSet:invalidCharacters] componentsJoinedByString:@""];

        return NO;
    } else {
        return YES;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top