TextField Validation With Regular Expression

I need help with code that looks at a textfield make sure it starts with either a (+ or -) then has 3 integers after it.

So valid data looks like +234 or -888

So I have started this code but there are 2 problems with it

  1. It correctly validates that only 4 characters are entered. But for some reason you have to take focus off the textfield in order for the Done button on the keyboard to fire and hide the keyboard. If I only put less than 4 characters in the textfield then the Done button works fine. But I dont want the user to enter anything but 4 characters and then press Done and hide the keyboard. Thats the first problem....

  2. I am not familar with regular expressions and how to use them in iphone. So I need to add to this code regular expression for the above requirement.

    -(BOOL)textField:(UITextField*)textFieldshouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
         NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
         return !([newString length] > 4);
    }
    //Done button to hide the keyboard
    -(IBAction)Done:(id)sender
    {
    
    }
    

Answers


I am not sure how you'd like to handle user input and feedback. First I'll show a simple way to keep the user in the editing mode of the textField if her input is not valid.

First of all two delegate methods:

- (BOOL)textFieldShouldReturn:(UITextField *)aTextField
{
    [aTextField resignFirstResponder];
    return YES;
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)aTextField
{
    return [self validateInputWithString:aTextField.text];
}

The testing method, which just returns YES or NO whether the input is valid or not:

- (BOOL)validateInputWithString:(NSString *)aString
{
    NSString * const regularExpression = @"^([+-]{1})([0-9]{3})$";
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regularExpression
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];
    if (error) {
        NSLog(@"error %@", error);
    }

    NSUInteger numberOfMatches = [regex numberOfMatchesInString:aString
                                                        options:0
                                                          range:NSMakeRange(0, [aString length])];
    return numberOfMatches > 0;
}

That's it. However I'd recommend showing some live status to the user whether his input is ok or not. Add the following notifcation, for example in your viewDidLoad method:

- (void)viewDidLoad
{
    // ...
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(validateInputCallback:) 
                                                 name:@"UITextFieldTextDidChangeNotification" 
                                               object:nil];
}

- (void)validateInputCallback:(id)sender
{
    if ([self validateInputWithString:textField.text]) {
        // For example turn a label green and let it say: "OK"
    } else {
        // For example turn a label red and let it say: "Allowed: + or minus followed by exactly three digits"
    }
}

Finally: If you need to access the capture groups (+ or - and the number) of the regular expression the following code will help:

// ... reg ex creation ...
NSArray *matches = [regex matchesInString:aString
                                  options:0
                                    range:NSMakeRange(0, [aString length])];

for (NSTextCheckingResult *match in matches) {
    for (int i = 0; i < [match numberOfRanges]; i++) {
        NSLog(@"range %d: %d %d", i, [match rangeAtIndex:i].location, [match rangeAtIndex:i].length);
        NSLog(@"substring %d: %@", i, [aString substringWithRange:[match rangeAtIndex:i]]);
    }
}

Validate Email id or Phone number using Regular Expression

Ddelegate methods:

- (BOOL)textFieldShouldReturn:(UITextField *)aTextField
{
    [aTextField resignFirstResponder];
    return YES;
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)aTextField
{
    return [self validateEmail:aTextField.text]; // Change validateEmail to validatePhone for phone validation.
}

Returns YES or NO whether the input is valid or not:

- (BOOL) validateEmail: (NSString *) candidate {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; 

    return [emailTest evaluateWithObject:candidate];
}

- (BOOL) validatePhone: (NSString *) candidate {
    NSString *phoneRegex = @"^+(?:[0-9] ?){6,14}[0-9]$"; 
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", phoneRegex]; 

    return [phoneTest evaluateWithObject:candidate];
}

Use UIPickerView instead

I am departing from the question title but IMHO considering what you need, it may be better to use UIPickerView to have a "spinning-wheel" type of entry, like you do in the Clock app when setting alarm. It can start at "+000" and user can tumble some of the four wheels ([+-]. [0-9], [0-9], [0-9]) as needed


Implement the -textField:shouldChangeCharactersInRange:replacementString in your UITextFieldDelegate and use NSRegularExpression to validate the changes.


Need Your Help

http_build_query with same name parameters

php http url

Is there a way to build a query automatically with http_build_query using parameters with the same name?

How can I achieve a slot machine spinning effect with CSS3 & jQuery?

jquery html css animation css3

I am creating a demo application that randomly selects a venue when a button is clicked. Once the button is clicked I want to have the venues scroll through with a slot machine spinning animation u...