I have five fields I need to validate, as different fields require a different range of numbers to have input by the user. The idea is when the user clicks to the next field it checks the previous field, however this isn't how it's working Is there a better way in my code to do this? I'd also like it when the user hits wrong info and disregards the error messages, it doesn't allow them to go to the next field. Below is my code: Code: - (void)textFieldDidEndEditing:(UITextField *)textField { //NSLog(@"BundlePath: %@", [[NSBundle mainBundle] bundlePath]); //declare the vars NSString *userNameOne = txtUserName.text; float numOne = [userNameOne intValue]; //age in years NSString *userNameTwo = txtUserName2.text; float numTwo = [userNameTwo intValue]; //iop NSString *userNameThree = txtUserName3.text; float numThree = [userNameThree intValue]; //cct NSString *userNameFour = txtUserName4.text; float numFour = [userNameFour intValue]; //psd NSString *userNameFive = txtUserName5.text; float numFive = [userNameFive intValue]; if(numOne < 40 || numOne > 100) { //play sound and vibrate for alert NSString *bonkSoundFile = [[NSBundle mainBundle] pathForResource:@"alertSound" ofType:@"mp3"]; NSURL *fileURL = [NSURL fileURLWithPath:bonkSoundFile]; SystemSoundID bonkSoundID; AudioServicesCreateSystemSoundID( (CFURLRef) fileURL, &bonkSoundID); AudioServicesPlaySystemSound(bonkSoundID); AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); //vibrate //show alert UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Age Error" message:@"Your age must be at least 40 years old and less than 100 years old" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } else if (numTwo < 20 || numTwo > 32) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"IOP Error" message:@"Your IOP must be between 20 and 32" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } else if (numThree < 475 || numThree > 650) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"CCT Error" message:@"Your CCT must be between 475 and 650" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } else if (numFour < .50 || numFour > 3.00) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"PSD Error" message:@"Your PSD must be between .50 and 3.00" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } else if (numFive < 0.80) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"C/D Error" message:@"Your C/D must be between 0 and .80" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } } And you can see a video of how it works (rather buggy) http://screencast.com/t/NWNjZTU2M Any advice would be greatly appreciated!
First, start with giving us more details on how it's "not working". Second, textFieldDidEndEditing: is passed the textField. I would use that in your logic. For example: Code: - (void)textFieldDidEndEditing:(UITextField *)textField { if (textField == txtUserName) { NSString *userNameOne = txtUserName.text; float numOne = [userNameOne intValue]; //age in years if(numOne < 40 || numOne > 100) { ...
I concur. I watched the video and based on the logic you provided, it will ALWAYS check the first field. Since you used a if ... else if ... endif construct, you're ALWAYS checking the first field. If it's OK, then it will check the second field, and so on. So, if in your video you had entered a valid number for the first field and an invalid for the second, it would trap on the second field for each of the subsequent fields. Checking the object passed in leaves me with an icky feeling, as I would have a validator object that would validate the fields as in an appropriate fashion. Going super-anal on the OO front, I would make the actual text field a subclass/implementation of a class that provided a validation method, and perhaps bounds for numeric validation, etc. However, using the if (textField == thisTextField) else if (textField == thatTextField) is OK if you must. Good luck moving forward. Ron
Ah right, great idea. So I've implemented your code suggestions and it works perfectly. Any way to modify this code so that if the user types in the wrong amount it won't go/allow option to the next field? Code: - (void)textFieldDidEndEditing:(UITextField *)textField { if (textField == txtUserName) { NSString *userNameOne = txtUserName.text; double numOne = [userNameOne intValue]; if(numOne < 40 || numOne > 100) { //play sound and vibrate for alert NSString *bonkSoundFile = [[NSBundle mainBundle] pathForResource:@"alertSound" ofType:@"mp3"]; NSURL *fileURL = [NSURL fileURLWithPath:bonkSoundFile]; SystemSoundID bonkSoundID; AudioServicesCreateSystemSoundID( (CFURLRef) fileURL, &bonkSoundID); AudioServicesPlaySystemSound(bonkSoundID); AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); //vibrate //show alert UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Age Error" message:@"Your age must be at least 40 years old and less than 100 years old" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } } else if (textField == txtUserName2) { NSString *userNameThree = txtUserName2.text; float numTwo = [userNameThree intValue]; if (numTwo < 20 || numTwo > 32) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"IOP Error" message:@"Your IOP must be between 20 and 32" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } } else if (textField == txtUserName3) { NSString *userNameThree = txtUserName3.text; float numThree = [userNameThree intValue]; if (numThree < 475 || numThree > 650) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"CCT Error" message:@"Your CCT must be between 475 and 650" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } } else if (textField == txtUserName4) { NSString *userNameFour = txtUserName4.text; float numFour = [userNameFour intValue]; if (numFour < .50 || numFour > 3.00) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"PSD Error" message:@"Your PSD must be between .50 and 3.00" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } } else if (textField == txtUserName5) { NSString *userNameFive = txtUserName5.text; float numFive = [userNameFive intValue]; if (numFive < 0.80) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"C/D Error" message:@"Your C/D must be between 0 and .80" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } } }
Yes. Basically you'll want the current field to remain as the first responder. Look into becomeFirstResponder.
So would it be something like this, Code: if (textField == txtUserName) { NSString *userNameOne = txtUserName.text; double numOne = [userNameOne intValue]; if(numOne < 40 || numOne > 100) { //play sound and vibrate for alert NSString *bonkSoundFile = [[NSBundle mainBundle] pathForResource:@"alertSound" ofType:@"mp3"]; NSURL *fileURL = [NSURL fileURLWithPath:bonkSoundFile]; SystemSoundID bonkSoundID; AudioServicesCreateSystemSoundID( (CFURLRef) fileURL, &bonkSoundID); AudioServicesPlaySystemSound(bonkSoundID); AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); //vibrate //show alert UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Age Error" message:@"Your age must be at least 40 years old and less than 100 years old" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; //allow text field to be first responder [txtUserName becomeFirstResponder]; } }
I just got back home and tired the code but it didn't work. I was thinking that would make the textField be FirstReponder but no! Any thoughts?