Textfield Input Validation in iPhone SDK - iphone

I have to put validation on a UITextField for user input.
The user must input into the textfield a value
i.e. 70-80 or 85 mean num-num or num
Right now, I just allow to user to input only digits& - but drawback is that user can also input - number of times.
// My code is as follow
NSCharacterSet * set = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789-"] invertedSet];
if (([txtMarks.text rangeOfCharacterFromSet:set].location != NSNotFound )||[txtMarks.text isEqualToString:#""] ) {
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:#"Error" message:#"Invalid Input" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alt show];
[alt release];
}

Simply Try this,
int times = [[txtMarks.text componentsSeparatedByString:#"-"] count]-1;
if(times>1)
{
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:#"Error" message:#"'-' used more than one" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alt show];
[alt release];
}
EDIT 1
Using NSPredicate we can do it. Try this,
NSString *regex = #"[0-9]+(-[0-9]+)?";
NSPredicate *testRegex = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", regex];
if([testRegex evaluateWithObject:textField.text])
NSLog(#"Match");
else
NSLog(#"Do not match");
Hope that can help.

Try this first find whether your string contains -
Here subtring is -
if ([txtMarks.text hasPrefix:#"-"]||[txtMarks.text hasSuffix:#"-"])
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"sorry " message:#"invalid inoput as it has - at start or end" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
else
{
NSRange textRange;
textRange =[string rangeOfString:substring];
if(textRange.location == NSNotFound)
{
//Does not contain the substring
NSlog(#" string contains only num")
}
else
{
int times = [[txtMarks.text componentsSeparatedByString:#"-"] count];
if(times==2)
{
Nslog(#"num-num input")
}
else
{
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:#"Error" message:#"'-' used more than one" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alt show];
[alt release];
}
}
}

Try it using the following regular expression, It restricts user to enter more than one -.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSString *expression = #"^([0-9]{1,}+)?(\\-([0-9]{1,})?)?$";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression
options:NSRegularExpressionCaseInsensitive
error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:newString
options:0
range:NSMakeRange(0, [newString length])];
if (numberOfMatches == 0)
{
return NO;
}
return YES;
}

Related

NSRegularExpression on NSString not working

InUITextBoxfield,i insert some value,and I Want to use RegularExpressions match the string ..now i want the text box text should be match for only numeric digits upto 3 when I press button then it should work...
What I am trying is which is not working::-
-(IBAction)ButtonPress{
NSString *string =activity.text;
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^[0-9]{1,3}$" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:#""];
if ([activity.text isEqualToString:modifiedString ])
{ // work only if this matches numeric value from the text box text
}}
- (BOOL)NumberValidation:(NSString *)string {
NSUInteger newLength = [string length];
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:#"1234567890"] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
return (([string isEqualToString:filtered])&&(newLength <= 3));
}
in your button action event just use this like bellow...
-(IBAction)ButtonPress{
if ([self NumberValidation:activity.text]) {
NSLog(#"Macth here");
}
else {
NSLog(#"Not Match here");
}
}
Your code replaces all matches with an empty string, so if there is a match, it will be replaced by an empty string and your check will never work. Instead, just ask the regular expression for the range of the first match:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^[0-9]{1,3}$" options:NSRegularExpressionCaseInsensitive error:NULL];
NSRange range = [regex rangeOfFirstMatchInString:string options:0 range:NSMakeRange(0, [string length])];
if(range.location != NSNotFound)
{
// The regex matches the whole string, so if a match is found, the string is valid
// Also, your code here
}
You can also just ask for the number of matches, if it's not zero, the string contains a number between 0 and 999 because your regex matches for the whole string.
Please try following code.
- (BOOL) validate: (NSString *) candidate {
NSString *digitRegex = #"^[0-9]{1,3}$";
NSPredicate *regTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", digitRegex];
return [regTest evaluateWithObject:candidate];
}
-(IBAction)btnTapped:(id)sender{
if([self validate:[txtEmail text]] ==1)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message" message:#"You Enter Correct id." delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message" message:#"You Enter Incoorect id." delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
}
}

Ensure User has entered email address string in correct format?

i have a text field in Contact screen and the user need to enter email address to send me message.
Whats the best way to ensure the user has entered a valid email address such as:
a#b.com / net / org / co.il
abc#gmail.com
abc#yahoo.com
etc..
Thanks
Try the following:
- (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 0;
return [emailTest evaluateWithObject:candidate];
}
-(IBAction)btnTapped:(id)sender{
if([self validateEmail:[txtEmail text]] ==1)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message" message:#"You Enter Correct Email id." delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message" message:#"You Enter Incoorect Email id." delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
}
}
Use this textField delegate function as this will be called on every text entered:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *strEnteredText = textField.text;
if(strEnteredText.length>0)
{
if([self validateEmail:strEnteredText])
{
//Valid email
//Use UILabel to give message
// BOOL email = true to know email is valid when submit button tapped
}
else
{
//Not Valid email
//Use UILabel to give message
// BOOl emaiL = false to know email is valid when submit button tapped
}
}
}
Add this method .h file
- (BOOL) validateEmail: (NSString *) enteredText
{
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:enteredText];
}
Swift
extension String {
func isValidEmail() -> Bool {
let emailRegEx = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,10}"
let emailTest = NSPredicate(format:"SELF MATCHES %#", emailRegEx)
let result = emailTest.evaluateWithObject(self)
return result
}
}
"jim#off.com".isValidEmail() //true
"jim.com".isValidEmail() // false

Delete key event in iPhone

I created UITextField. I need only 4 numeric characters only allowed that textfield.
I used the following code and get result.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber* candidateNumber;
NSString* candidateString = [textField.text stringByReplacingCharactersInRange:range withString:string];
range = NSMakeRange(0, [candidateString length]);
[numberFormatter getObjectValue:&candidateNumber forString:candidateString range:&range error:nil];
NSUInteger newLength = [passwordfield.text length];
if(newLength>=4)
{
[passwordfield setText:[passwordfield.text substringToIndex:3]];
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setTitle:#"Alert"];
[alert setMessage:#"Four Characters only allowed.."];
[alert setDelegate:self];
[alert addButtonWithTitle:#"Ok"];
[alert show];
}
if (([candidateString length] > 0) && (candidateNumber == nil || range.length < [candidateString length]))
{
return NO;
}
else
{
return YES;
}
}
But my problem is when I press delete key, last two characters are deleting
and same time alertview also display.
How to solve this issue?
You're making this more complex than it needs to be. When a user taps the backspace key, the incoming string is a blank string; [NSString string]. Here's a working solution:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
if (![numberFormatter numberFromString:string] && ![string isEqualToString:[NSString string]]) {
return NO;
}
if (textField.text.length + string.length > 4) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"Four Characters only allowed..."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
return NO;
} else {
return YES;
}
}

UIAlert View-for yes/no condition

my app needs alert msg and if yes button pressed then one more alert msg and then i have to called a method.This is my code:
-(IBAction)resetPressed:(id)sender
{
NSString *title= [NSString stringWithFormat:#"Warning"];
NSString *message = [NSString stringWithFormat:#"Are you sure you want to Reset"];
NSString *ok = [NSString stringWithFormat:#"No"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView.tag ==1)
{
NSString *title= [NSString stringWithFormat:#"Warning"];
NSString *message = [NSString stringWithFormat:#"Are you sure you want to Reset"];
NSString *ok = [NSString stringWithFormat:#"No"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
alert.tag =2;
[alert show];
[alert release];
}
else if(alertView.tag ==2)
{
[self resetArray];
}
}
Thanks.
I'm not sure what your goal is but a few things look wrong to me anyways:
First of all you should create your strings this way:
NSString *title= #"Warning";
There's no need to use stringWithFormat in your case.
Then, it doesn't seem you properly set the first UIAlert's tag to 1, and the default value for tags is 0 so I guess the if statements in didDismissWithButtonIndex are never true.
Also, you should check which button was pressed using buttonIndex, otherwise you are going to show both alert and call [self resetArray] whichever button is pressed by the user.
Hope that helps.
In your code, you create the first alert, but never actually set the tag on it. You should do:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
alert.tag = 1; //Or 2, or something.
[alert show];
[alert release];
Then the code in your delegate method will run.
Please define two separate UIAlertView in .h file
#interface XYZViewController:UIViewController
{
UIAlertView *firstAlertView;
UIAlertView *secondAlertView;
}
Now in your .m file modify as below:
-(IBAction)resetPressed:(id)sender
{
NSString *title= [NSString stringWithFormat:#"Warning"];
NSString *message = [NSString stringWithFormat:#"Are you sure you want to Reset"];
NSString *ok = [NSString stringWithFormat:#"No"];
if(firstAlertView == nil)
{
firstAlertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
}
[firstAlertView show];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView == firstAlertView)
{
NSString *title= [NSString stringWithFormat:#"Warning"];
NSString *message = [NSString stringWithFormat:#"Are you sure you want to Reset"];
NSString *ok = [NSString stringWithFormat:#"No"];
if(secondAlertView == nil)
{
secondAlertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
}
[secondAlertView show];
}
else if(alertView == secondAlertView)
{
[self resetArray];
}
}
and in dealloc method please release the allocated UIAlertviews.
Hope i am clear to you.
Thanks,
Jim.

becomeFirstResponder not working!

In the below code becomeFirstResonder not working, only resignFirstresponder working...can anyone please help
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == txtDate)
{
[txtDate resignFirstResponder];
[txtTime becomeFirstResponder];
}
if (textField == txtTime)
{
[txtTime resignFirstResponder];
[txtAddress becomeFirstResponder];
}
if (textField == txtAddress)
{
[txtAddress resignFirstResponder];
[txtCity becomeFirstResponder];
}
if (textField == txtCity)
{
[txtCity resignFirstResponder];
[txtState becomeFirstResponder];
}
if(textField == txtState)
{
[txtState resignFirstResponder];
[txtZip becomeFirstResponder];
}
if (textField == txtZip)
{
[txtZip resignFirstResponder];
}
return NO;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
if(textField == txtDate)
{
NSString *dateString = txtDate.text;
NSString *dateRegex = #"^(1[0-2]|0[1-9])/(3[01]|[12][0-9]|0[1-9])/[0-9]{4}$";
NSPredicate *dateTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", dateRegex];
BOOL validateDate = [dateTest evaluateWithObject:dateString];
if(!validateDate){
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Date Error." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtDate.text = nil;
}
}
if(textField == txtTime)
{
NSString *timeString = txtTime.text;
NSString *timeRegex = #"^(([0]?[0-5][0-9]|[0-9]):([0-5][0-9]))$";
NSPredicate *timeTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", timeRegex];
BOOL validateTime = [timeTest evaluateWithObject:timeString];
if(!validateTime) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect Time Entry." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtTime.text = nil;
}
}
if(textField == txtAddress)
{
NSString *addressString = txtAddress.text;
NSString *addressRegex = #"^[a-z0-9 ]+$";
NSPredicate *addressTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", addressRegex];
BOOL validateAddress = [addressTest evaluateWithObject:addressString];
if(!validateAddress) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect State." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtAddress.text = nil;
}
}
if(textField == txtState)
{
NSString *stateString = txtState.text;
NSString *stateRegex = #"^(?-i:A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
NSPredicate *stateTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", stateRegex];
BOOL validateState = [stateTest evaluateWithObject:stateString];
if(!validateState) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect State." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtState.text = nil;
}
}
if(textField == txtCity)
{
NSString *cityString = txtCity.text;
NSString *cityRegex = #"^[a-z ]+$";
NSPredicate *cityTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", cityRegex];
BOOL validateCity = [cityTest evaluateWithObject:cityString];
if(!validateCity) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect City." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtCity.text = nil;
}
}
if(textField == txtZip)
{
NSString *zipString = txtZip.text;
NSString *zipRegex = #"^[0-9]{5}([- /]?[0-9]{4})?$";
NSPredicate *zipTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", zipRegex];
BOOL validateZip = [zipTest evaluateWithObject:zipString];
if(!validateZip) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect Zip." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtZip.text = nil;
}
}
return NO;
}
You should not do this in textFieldShouldReturn. Try doing this in textFieldDidEndEditing.
In
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
In
- (BOOL)textFieldDidEndEditing:(UITextField *)textField
{
if (textField == txtDate)
{
[txtTime becomeFirstResponder];
}
if (textField == txtTime)
{
[txtAddress becomeFirstResponder];
}
if (textField == txtAddress)
{
[txtCity becomeFirstResponder];
}
if (textField == txtCity)
{
[txtState becomeFirstResponder];
}
if(textField == txtState)
{
[txtZip becomeFirstResponder];
}
if (textField == txtZip)
{
//[txtZip resignFirstResponder];
}
}
You don't need the resignFirstResponder calls in there if you're assigning the firstResponder at the same time. That may be confusing things. Also, verify the fields are configured properly; are you able to tap on them to set their firstResponder status?
we must ensure the METHOD becomeFirstResponder be performed on mainThread
so make it like :
[xxx performSelectorOnMainThread:#selector(becomeFirstResponder) withObject:nil waitUntilDone:NO];