-1

I have 3 UITextField which receive user input. The UITextField represent

  • day
  • month
  • year

I would like to know how to restrict the user from inputting incorrect values into these UITextField.

For example, number of days (1-31); if the user types 9 first, he is unable to type anything else after, as 9 is the only day in the month.

Or another example would be month (1-12); if the user types 5 thats their only option?

halfer
  • 19,824
  • 17
  • 99
  • 186
HurkNburkS
  • 5,492
  • 19
  • 100
  • 183
  • Look for UITextField delegate function like defined here https://developer.apple.com/library/ios/documentation/uikit/reference/UITextFieldDelegate_Protocol/UITextFieldDelegate/UITextFieldDelegate.html – iphonic Apr 07 '14 at 10:32
  • Yep, I have added the UITextField delegates however I am unsure in regards to how to achive this using NSRegularExpression – HurkNburkS Apr 07 '14 at 10:54
  • I think, you will find `NSRegularExpression` bit complex if you don't understand this. But you actually do it in different way, by simple checking the input from textfield. For eg: if(textfield.length==1)return; //Don't allow input.. – iphonic Apr 07 '14 at 11:11
  • @HurkNburkS : Try that code for dayText & validate it for one days (1,2,3 4-9) , two days (1-19, 2-29) but of course fails for 3-39. – Balram Tiwari Apr 07 '14 at 11:15

4 Answers4

2

You need to implement the UITextFieldDelegate to handle text change during user's typing so that you will accept those characters that are needed and reject those character that are non required.

You can use NSRegularExpression to simply check if it matches the day,month or year pattern.

Described in this

Community
  • 1
  • 1
Faisal Ali
  • 1,135
  • 10
  • 17
1

You can use the delegate as this to have the feature you need.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

BOOL returnValue = NO;
NSMutableString *stringValue = [NSMutableString stringWithString:[textField text]];
[stringValue insertString:string atIndex:range.location];

if(textField == dayField){
    if([stringValue intValue]>=0 && [stringValue intValue]<=31 && [stringValue intValue])
        returnValue = YES;
}

if(textField == monthField){
    if([stringValue intValue]>=0 && [stringValue intValue]<=12 && [stringValue intValue])
        returnValue = YES;
}

return returnValue;

}

This will also check for the numbers only scenario.

borncrazy
  • 1,589
  • 1
  • 12
  • 9
0

You should better use UIPickerView with valid dates, months and years as a datasource. It should be good start.

EDIT:

Based on the discussion below, I would suggest you to make your UITextFields of a fixed length and once the text ends edit compare it numerically like:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
    NSUInteger newLength = [textField.text length] + [string length] - range.length;

    if([textField isEqual:DayTextField])   // `DayTextField` refers to textfield that represents day
    {
        return (newLength > 2);
    }
    // else if .....

    return NO;
}

-(BOOL)textFieldShouldReturn:(UITextField *)textField 
{
   if([textField isEqual:DayTextField])
   {
       int val = [textField.text integerValue];
       if( 1 <= val <= 31)
       {
           NSLog(@"Valid range");
       }
       else
       {
           NSLog(@"Invalid range");          
           // clear day textfield
       }
   }
}
NeverHopeless
  • 11,077
  • 4
  • 35
  • 56
  • 1
    @Downvoter, you would be superb if you tell me the reason too. possibly i would modify the solution. I do not bite :) – NeverHopeless Apr 07 '14 at 10:47
  • I downvoted you I understand its a solution however I am looking inparticular how to achive this using UITextfields as UIPickers are not an option in the current view I would like to make. I know your option is not techniqually incorrect however I would like to achive this without UIPickerViews. – HurkNburkS Apr 07 '14 at 10:53
  • Ok i came up with an option and now its upto you, but i don't see any point of not using it (unless you have any specific requirement) since it avoids to validate user input. Also, using regex it would be difficult to handle feb 28 and 29 since regex don't know its a leap year or not unless you end up with a long regex. – NeverHopeless Apr 07 '14 at 10:58
  • I will not be compairing between UITextFields (Day / Month / Year) I simply want to make sure that any value entered into the day field is 1-31, then month 1-12 year 0000-9999. – HurkNburkS Apr 07 '14 at 11:03
0

For you the solution is to Assign a Tag value to each TextField & then conform to UITextFieldDelegate & follow this implementation.

  • You have to do something like this for month & year text as well. The approach is simple.
  • If user types any thing except 123 for day, he should be allowed to type 1 digit only.
  • If user types any digit from the set 123, he should be allowed to type 2 digits only.

    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    
    if(textField.tag == kTagDayText){
    if([textField.text length] <=2){
        if([textField.text length] == 1){
            NSCharacterSet *monthTwoDigitsNumbers = [NSCharacterSet characterSetWithCharactersInString:@"123"];
            NSCharacterSet *characterSetTwoDigit = [NSCharacterSet characterSetWithCharactersInString:textField.text];
    
            BOOL stringIsValid = [monthTwoDigitsNumbers isSupersetOfSet:characterSetTwoDigit];
            return stringIsValid;
        }else {
            NSCharacterSet *monthOneDigitsNumbers = [NSCharacterSet characterSetWithCharactersInString:@"456789"];
            NSCharacterSet *characterSetOneDigit = [NSCharacterSet characterSetWithCharactersInString:textField.text];
    
            BOOL stringIsValid = [monthOneDigitsNumbers isSupersetOfSet:characterSetOneDigit];
            return stringIsValid;
        }
      }
    }
    
    return ([string stringByTrimmingCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].length > 0) || [string isEqualToString:@""];
    
    }
    

Hope that gives some idea.

Balram Tiwari
  • 5,657
  • 2
  • 23
  • 41
  • I know there is some more to add to this code, which should be added to make it work fine for days starting with 3 as valid only days are 30 & 31, but not 32-39. But this works fine for 4-9 (one days) & (1-19) & (2-29). – Balram Tiwari Apr 07 '14 at 11:12