39

How can I restrict special characters in a UITextField except dot and underscores?

I have tried the code snippet below, but without luck:

#define ACCEPTABLE_CHARECTERS @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_." - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSCharacterSet *acceptedInput = [NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARECTERS]; if (![[string componentsSeparatedByCharactersInSet:acceptedInput] count] > 1){ NSLog(@"not allowed"); return NO; } else{ return YES; } } 
3

10 Answers 10

112

Try code block given below, it worked fine for me.

SWIFT 3.0

let ACCEPTABLE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_" func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let cs = NSCharacterSet(charactersIn: ACCEPTABLE_CHARACTERS).inverted let filtered = string.components(separatedBy: cs).joined(separator: "") return (string == filtered) } 

Objective C

#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]; } 

Hope it will work for you as well.

Sign up to request clarification or add additional context in comments.

6 Comments

It should be return ![string isEqualToString:filtered];
@Fogh he is already using the invertedSet method so we don't need to include ! in the return statement.
Seems a bit excessive to split something up, join it back together and then see if the two match when all you really need to do is count how many components there are after the split. If there's more than one, you already know there are unwanted characters.
Swift version here, let ALLOWED_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_."; func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let set = CharacterSet(charactersIn: ALLOWED_CHARS); let filtered = string .components(separatedBy: set) .joined(separator: ""); return filtered != string; }
@ElegyD, you should add Swift 4 version, not replace Swift 3 version with Swift 4.
|
4

Try this

NSCharacterSet *set= [NSCharacterSet symbolCharacterSet]; if ([string rangeOfCharacterFromSet:[set invertedSet]].location == NSNotFound) { // valid } else { // invalid } 

you can make your own set with

NSCharacterSet *set= [NSCharacterSet characterSetWithCharactersInString:@"<all your symbols you want to ignore>"]; 

1 Comment

Change symbolCharacterSet to ACCEPTABLE_CHARECTERS and this will work how he wants....
4

Swift 4

let RISTRICTED_CHARACTERS = "'*=+[]\\|;:'\",<>/?%" 

UITextField delegate method:

func textField(_ textField: UITextField, shouldChangeCharactersIn _: NSRange, replacementString string: String) -> Bool { let set = CharacterSet(charactersIn: RISTRICTED_CHARACTERS) let inverted = set.inverted let filtered = string.components(separatedBy: inverted).joined(separator: "") return filtered != string } 

2 Comments

This has a bug in it that the return bool should be == and not !=. Currently it will allow all characters except the restricted.
This doesn't work for case string == "" (for example clearing input)
4

Swift 5 solution

let ACCEPTABLE_CHARACTERS = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_." func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let cs = CharacterSet(charactersIn: ACCEPTABLE_CHARACTERS).inverted let filtered: String = (string.components(separatedBy: cs) as NSArray).componentsJoined(by: "") return (string == filtered) } 

1 Comment

Works in Swift 5.x too.
3

NSString *Regex = @"[A-Za-z0-9^]*";

NSPredicate *TestResult = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", Regex];

[TestResult evaluateWithObject:@"YourTestString"];

Last return boolean value true/false

In Method

+ (BOOL) validateSpecialCharactor: (NSString *) text { NSString *Regex = @"[A-Za-z0-9^]*"; NSPredicate *TestResult = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", Regex]; return [TestResult evaluateWithObject:text]; } 

Comments

3

Swift 2.2 based on Mrunal's answer:

let notAllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."; func textField( textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let set = NSCharacterSet(charactersInString: notAllowedCharacters); let inverted = set.invertedSet; let filtered = string .componentsSeparatedByCharactersInSet(inverted) .joinWithSeparator(""); return filtered == string; } 

2 Comments

Can i add 'if string == "" {return true}'?
@a.u.b I don't think the replacement string can ever be empty, but give it a try
1

This may help you try this.. and let me know please

-(BOOL)isHaveSpecialChar:(NSString*)str{ NSString *customStr = @"~`!@#$%^&*()+=-/;:\"\'{}[]<>^?, "; NSCharacterSet *alphaSet = [NSCharacterSet characterSetWithCharactersInString:customStr]; BOOL isHaveSpecialChar = [[str stringByTrimmingCharactersInSet:alphaSet] isEqualToString:@""]; return !isHaveSpecialChar; } 

1 Comment

This is wrong - it will only return YES if every character in str is a character in customStr.
1
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let set = NSCharacterSet(charactersIn: "0123456789") let inverted = set.inverted; let filtered = string.components(separatedBy: inverted).joined(separator: "") return filtered == string; 

Comments

0
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let cs = NSCharacterSet.decimalDigits.inverted let filtered = string.components(separatedBy: cs).joined(separator: "") return (string == filtered) } 

Comments

-1

Try this:

NSString *str = @"___asdf.SHiv._.l.asg. g.g._ASdgASG_.......asfgads.g. .._____fdgdsfghsdfgh"; str= [str stringByReplacingOccurrencesOfString:@"." withString:@""]; str=[str stringByReplacingOccurrencesOfString:@"_" withString:@""]; str=[str stringByReplacingOccurrencesOfString:@" " withString:@""]; str=[str stringByTrimmingCharactersInSet:[NSCharacterSet alphanumericCharacterSet]]; if ([str isEqualToString:@""]) { NSLog(@"valid"); } else { NSLog(@"invalid"); } 

1 Comment

This is an extremely roundabout. Regular expressions are built for exactly this kind of thing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.