4

I want to my uitextfield be like XXX.XXX.XXX/XX at the end of typing.

To limit the lenght I use this:

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

        NSUInteger newLength = [textField.text length] + [string length] - range.length;
        NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS_ONLY] invertedSet];
        NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
        return (([string isEqualToString:filtered])&&(newLength <= CHARACTER_LIMIT));
    } else{
        return YES;
    }

}

The problem is how to insert the "." and "/" while user still editing it.

Marckaraujo
  • 7,422
  • 11
  • 59
  • 97
  • This answer may help if you are looking for dynamic approach. http://stackoverflow.com/a/38560759/3947151 – Tesan3089 Jul 25 '16 at 06:18

3 Answers3

12

The following code should do the following:

  1. Limit the number of characters that can be typed/pasted into the text field
  2. Automatically add periods and slashes at the appropriate locations
  3. Prevent issues from the user copy/pasting a string that already has the necessary periods/slashes

That said, there is almost certainly more efficient ways to do this; but if you're not concerned about code length it'll do the trick just fine.

- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSString *text = textField.text;

    // If we're trying to add more than the max amount of characters, don't allow it
    if ([text length] == 14 && range.location > 13) {
          return NO; 
    }

    // First lets add the whole string we're going for
    text = [text stringByReplacingCharactersInRange:range withString:string];

    // Now remove spaces, periods, and slashes (since we'll add these automatically in a minute)
    text = [text stringByReplacingOccurrencesOfString:@" " withString:@""];
    text = [text stringByReplacingOccurrencesOfString:@"." withString:@""];
    text = [text stringByReplacingOccurrencesOfString:@"/" withString:@""];

    // We need to use an NSMutableString to do insertString calls in a moment
    NSMutableString *mutableText = [text mutableCopy];

    // Every 4th char will be a '.', but we don't want to check more than the first 8 characters
    for (NSUInteger i = 3; i < mutableText.length && i < 8; i += 4) {
        [mutableText insertString:@"." atIndex:i];
    }
    // If the text is more than 11 characters, we also want to insert a '/' at the 11th character index
    if (mutableText.length > 11) {
        [mutableText insertString:@"/" atIndex:11];
    }

    // lets set text to our new string
    text = mutableText;

    // Now, lets check if we need to cut off extra characters (like if the person pasted a too-long string)
    if (text.length > 14) {
        text = [text stringByReplacingCharactersInRange:NSMakeRange(14, mutableText.length-14) withString:@""];
    }

    // Finally, set the textfield to our newly modified string!
    textField.text = text;

    return NO;
}
Doc
  • 1,480
  • 2
  • 16
  • 28
  • I am validating a textfield to only accept `XX ## ## ## X` (UK National Insurance number format), and was able to use this code to achieve this - I just added a simple `for` loop with some `if` tests to check the character index and return `NO` unless it passes the test. Your code is very helpful, thanks a lot! – rosshump Oct 29 '14 at 13:22
  • Great code. Easy to put straight in. Do you know if there is an easy way to make the '.' appear immediately after typing it rather than waiting until the next key is typed? – sam_smith Jan 12 '15 at 06:27
  • @weesplodge I assume you mean that, for example, if the user typed in only three characters, a period would appear without them having to type in a fourth character? If so, you could simply check the length of the text and, if it's an appropriate length (example: 3), insert a period at the end. – Doc Jan 12 '15 at 15:43
  • Thanks @Doc i have create UK National Insurance Number from chang ur code – Harshil Kotecha Sep 18 '18 at 07:55
3
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSString *text = textField.text;
    text = [text stringByReplacingCharactersInRange:range withString:string];
    text = [text stringByReplacingOccurrencesOfString:@"." withString:@""];

    // Do your length checking here

    NSMutableString *mutableText = [text mutableCopy];

    // Every 4th char will be a .
    for (NSUInteger i = 3; i < mutableText.length; i += 4) {
        [mutableText insertString:@"." atIndex:i];
    }

    textField.text = mutableText;

    return NO;
}
Danilo
  • 3,257
  • 2
  • 19
  • 24
  • doesnt work your solution, it keeps adding dot and you can't use backspace also. – Marckaraujo Jan 06 '14 at 18:54
  • You do know that you can do some thinking on your own? This was to give you a direction, not provide you with a full solution. – Danilo Jan 06 '14 at 21:21
  • On line 4 i had a space instead of a dot (now edited), now its working as intended: every 4th char is a dot. You should really be able to figure this out with the help i provided to get a full solution. – Danilo Jan 06 '14 at 21:28
  • 1
    Danilo's solution, while broken (at least originally) and not meeting all the requirements, was not too far off. The solution I provided simply meets all the requirements plus a couple which I assumed would be desired. Honestly, I used Danilo's original code as a basic starting point before adding all the rest of the stuff. +1 to get it out of the neg. – Doc Jan 07 '14 at 02:06
1

UK National Insurance Number Text Field

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField == _txtNationalInsuranceNumber) {
        NSString *text = textField.text;

        // If we're trying to add more than the max amount of characters, don't allow it
        if ([text length] == 13 && range.location > 12) {
            return NO;
        }

        // First lets add the whole string we're going for
        text = [text stringByReplacingCharactersInRange:range withString:string];

        // Now remove spaces, periods, and slashes (since we'll add these automatically in a minute)
        text = [text stringByReplacingOccurrencesOfString:@" " withString:@""];


        // We need to use an NSMutableString to do insertString calls in a moment
        NSMutableString *mutableText = [text mutableCopy];

        // Every 4th char will be a '.', but we don't want to check more than the first 8 characters
        for (NSUInteger i = 2; i < mutableText.length && i < 10; i += 3) {
            [mutableText insertString:@" " atIndex:i];
        }
        // If the text is more than 11 characters, we also want to insert a '/' at the 11th character index
        if (mutableText.length > 11) {
            [mutableText insertString:@" " atIndex:11];
        }

        // lets set text to our new string
        text = mutableText;

        // Now, lets check if we need to cut off extra characters (like if the person pasted a too-long string)
        if (text.length > 14) {
            text = [text stringByReplacingCharactersInRange:NSMakeRange(14, mutableText.length-14) withString:@""];
        }

        // Finally, set the textfield to our newly modified string!
        textField.text = text;

        return NO;
    }
    else
    {
        return  YES;
    }


}
Harshil Kotecha
  • 2,846
  • 4
  • 27
  • 41