36

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;
        }
}
Tamás Sengel
  • 47,657
  • 24
  • 144
  • 178
Graham Bell
  • 1,109
  • 1
  • 13
  • 30

10 Answers10

104

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.

Piyush Sanepara
  • 1,397
  • 1
  • 17
  • 21
Mrunal
  • 13,474
  • 6
  • 48
  • 91
  • It should be `return ![string isEqualToString:filtered];` – Fogh Feb 10 '15 at 07:23
  • 3
    @Fogh he is already using the `invertedSet` method so we don't need to include `!` in the return statement. – iSee Apr 30 '15 at 09:55
  • Thank you. Its Working fine. – ssowri1 Dec 22 '16 at 11:43
  • 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. – Ash Mar 21 '17 at 08:36
  • 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; } – Anjum Shrimali Apr 03 '17 at 11:32
  • @ElegyD, you should **add** Swift 4 version, not replace Swift 3 version with Swift 4. – user28434'mstep Feb 08 '18 at 11:42
  • What's the hell is going here? 1)`NSCharacterSet` from objective-c in swift while siwft has its own character set class; 2)`inverted` is totally extra - you can just use the opposite condition; 3)conversions string->array->string. Why not to replace your code in the `UITextField`'s delegate method with just one line: `return CharacterSet(charactersIn: string).isSubset(of: allowedCharacterSet)`? It is an example for **Swift 4.2** – Vyachaslav Gerchicov Jan 29 '19 at 09:02
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>"];
amar
  • 4,147
  • 6
  • 35
  • 48
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];
}
ChintaN -Maddy- Ramani
  • 5,006
  • 1
  • 24
  • 46
Indra
  • 528
  • 2
  • 11
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;

}
Community
  • 1
  • 1
Evdzhan Mustafa
  • 3,126
  • 1
  • 20
  • 37
3

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
}
Sunil Targe
  • 7,009
  • 5
  • 42
  • 71
2

Swift 3.1 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)
    }
Sourabh Sharma
  • 7,426
  • 4
  • 62
  • 75
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;
}
SachinVsSachin
  • 6,193
  • 2
  • 31
  • 37
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;
GOWTHAM
  • 13
  • 4
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)
}
-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");
    }
shivam
  • 1,148
  • 1
  • 11
  • 28