Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS automatically add hyphen in text field

I'm learning iOS development and am having a hard time figuring out the various events for the controls. For a test I have a UITextField where the user is meant to input a string in the format: XXXX-XXXX-XXXX-XXXX

I want to be able to check how long the text in the field is after each entry and see if it needs to have a hyphen appended to it. I've set up my IBAction function for this but when I assign it to the "Value Changed" event it does nothing, it works fine when I set it on the "Editing Did End" but that will only call when the user exits the control.

Edit: Just to add, the "Editing Changed" event causes it to crash too. I assume this is a stack overflow or something where the setting of the text calls the event handler again.

So in short, is there any way to set an event handler for each time the user enters a character in the UITextField?

like image 959
123 Avatar asked Aug 06 '11 17:08

123


People also ask

How can I type a hyphen using the keypad on iPhone 6?

How can I type a hyphen using the keypad of my iPhone 6? You can't. There are no hyphens on the numbered keypad on an iPhone or any Phone really. Only numbers or corresponding letters. Are you sure they asked for a hyphenated code?

How do you hyphenate on a phone dial array?

If you mean from the Phone app, you can't (any more than you could on a regular phone). There is no hyphen key on a phone dial array.

How to add a dash or hyphen to a string?

The onkeyup event of the input box will call a function, which will automatically add or insert a dash (-) or a hyphen to the string, using Regex. The Markup and the Script <html> <head> <title>Add Hyphen to a text using JavaScript</title> </head> <body> <p>Type some values (numbers or text) in the text box.

Why can't you put a hyphen in phone numbers?

Some may use either the * or the # as a place holder for a special character. But that would be specific for the system you were interacting with. If you mean from the Phone app, you can't (any more than you could on a regular phone). There is no hyphen key on a phone dial array.


2 Answers

Be aware the previous answer is woefully inadequate. Heaven forbid your user enter an incorrect digit and dare attempt to delete it! In fairness, the poster noted the code may not work perfectly. But then, it wouldn't even compile, so the buyer beware filter should already be high. If you fix the compile error and try the code, you'll see you can easily end up with input that does not match the poster's stated format.

Here's a solution I've used for restricting a text field to a phone number of the format 123-456-7890. Adjusting for other numeric formats is trivial. Note the use of the passed NSRange. And BTW, rejecting non-digit characters is needed even when using a numeric virtual keyboard since users can still enter non-digits via a hardware keyboard.

One other note. I add the hyphen after the entry of the 4th and 7th digits to make the deleting of digits a bit easier. If you add after the 3rd and 6th digits, you will have to handle the case of deleting the dangling hyphen. The code below avoids that use case.

// Restrict entry to format 123-456-7890
- (BOOL)                textField:(UITextField *)textField
    shouldChangeCharactersInRange:(NSRange)range
                replacementString:(NSString *)string {

  // All digits entered
  if (range.location == 12) {
    return NO;
  }

  // Reject appending non-digit characters
  if (range.length == 0 &&
       ![[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[string characterAtIndex:0]]) {
    return NO;
  }

  // Auto-add hyphen before appending 4rd or 7th digit
  if (range.length == 0 &&
      (range.location == 3 || range.location == 7)) {
    textField.text = [NSString stringWithFormat:@"%@-%@", textField.text, string];
    return NO;
  }

  // Delete hyphen when deleting its trailing digit 
  if (range.length == 1 &&
      (range.location == 4 || range.location == 8))  {
    range.location--;
    range.length = 2;
    textField.text = [textField.text stringByReplacingCharactersInRange:range withString:@""];
    return NO;
  }

  return YES;
}
like image 100
dingo sky Avatar answered Sep 19 '22 02:09

dingo sky


dingo sky's answer is good, but in the intrest of helping future people that stumble on this solution, there are a couple problems. Dingo's solution allows you to paste long numeric strings into the field that break the "rules" of the delegate, since it's only using the range location for formatting and length. (you can have more than 12 characters and not have the hyphens).

Simple solution is to calculate the length of the resulting string, and reformat it each time.

An updated version of Dingo's answer is below:

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

    //calculate new length
     NSInteger moddedLength = textField.text.length-(range.length-string.length);

    // max size.
    if (moddedLength >= 13) {
        return NO;
    }

    // Reject non-number characters
    if (range.length == 0 &&![[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[string characterAtIndex:0]]) {
        return NO;
    }

    // Auto-add hyphen before appending 4rd or 7th digit
    if ([self range:range ContainsLocation:3] || [self range:range ContainsLocation:7]) {
        textField.text = [self formatPhoneString:[textField.text stringByReplacingCharactersInRange:range withString:string]];
        return NO;
    }

    return YES;
}

#pragma mark helpers

-(NSString*) formatPhoneString:(NSString*) preFormatted
{
    //delegate only allows numbers to be entered, so '-' is the only non-legal char.
    NSString* workingString = [preFormatted stringByReplacingOccurrencesOfString:@"-" withString:@""];

    //insert first '-'
    if(workingString.length > 3)
    {
        workingString = [workingString stringByReplacingCharactersInRange:NSMakeRange(3, 0) withString:@"-"];
    }

    //insert second '-'
    if(workingString.length > 7)
    {
        workingString = [workingString stringByReplacingCharactersInRange:NSMakeRange(7, 0) withString:@"-"];
    }

    return workingString;

}

-(bool) range:(NSRange) range ContainsLocation:(NSInteger) location
{
    if(range.location <= location && range.location+range.length >= location)
    {
        return true;
    }

    return false;
}
like image 42
Nyth Avatar answered Sep 20 '22 02:09

Nyth