user2415313
user2415313

Reputation: 101

UITextField input mask?

http://sublime.nyasha.me/admin/form_masks.html

I use this technique to achieve nice results with html/css/java etc, but how does one achieve this in objective-c?

I've read so far about number formatting, but how can I literally have it so when the content is editable it displays the formatted version as they're typing and doesn't allow them to exceed .length in certain areas.

My example I need to use it for is

00:00:00 or 00h:00m:00s so when edited it will achieve __:__:__ or __h:__m:__s I've been scraping through the interwebs and cannot find such a technique, so far I've considered programatically doing something like this..

3x UITextField 1x UILabel

if (editing is commenced && value changed) {
    if (.length == 2) {
        Move onto next UITextField;
    }
} 

And display the UILabel Masked over the textfields, but also customise the textfields so 3 appears to be one.

-- EDIT

//Programming the Textfield Mask
-(void)reformatAsCardNumber:(UITextField *)textField
{
    NSUInteger targetCursorPosition =
    [textField offsetFromPosition:textField.beginningOfDocument
                       toPosition:textField.selectedTextRange.start];

    NSString *cardNumberWithoutSpaces =
    [self removeNonDigits:textField.text
andPreserveCursorPosition:&targetCursorPosition];

    if ([cardNumberWithoutSpaces length] > 6) {
        [textField setText:previousTextFieldContent];
        textField.selectedTextRange = previousSelection;
        return;
    }

    NSString *cardNumberWithSpaces =
    [self insertSpacesEveryFourDigitsIntoString:cardNumberWithoutSpaces
                      andPreserveCursorPosition:&targetCursorPosition];

    textField.text = cardNumberWithSpaces;
    UITextPosition *targetPosition =
    [textField positionFromPosition:[textField beginningOfDocument]
                             offset:targetCursorPosition];

    [textField setSelectedTextRange:
     [textField textRangeFromPosition:targetPosition
                           toPosition:targetPosition]
     ];
}

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

    return YES;
}

- (NSString *)removeNonDigits:(NSString *)string
    andPreserveCursorPosition:(NSUInteger *)cursorPosition
{
    NSUInteger originalCursorPosition = *cursorPosition;
    NSMutableString *digitsOnlyString = [NSMutableString new];
    for (NSUInteger i=0; i<[string length]; i++) {
        unichar characterToAdd = [string characterAtIndex:i];
        if (isdigit(characterToAdd)) {
            NSString *stringToAdd =
            [NSString stringWithCharacters:&characterToAdd
                                    length:1];

            [digitsOnlyString appendString:stringToAdd];
        }
        else {
            if (i < originalCursorPosition) {
                (*cursorPosition)--;
            }
        }
    }

    return digitsOnlyString;
}
- (NSString *)insertSpacesEveryFourDigitsIntoString:(NSString *)string
                          andPreserveCursorPosition:(NSUInteger *)cursorPosition
{
    NSMutableString *stringWithAddedSpaces = [NSMutableString new];
    NSUInteger cursorPositionInSpacelessString = *cursorPosition;
    for (NSUInteger i=0; i<[string length]; i++) {
        if ((i>0) && ((i % 2) == 0)) {
            [stringWithAddedSpaces appendString:@":"];
            if (i < cursorPositionInSpacelessString) {
                (*cursorPosition)++;
            }
        }
        unichar characterToAdd = [string characterAtIndex:i];
        NSString *stringToAdd =
        [NSString stringWithCharacters:&characterToAdd length:1];

        [stringWithAddedSpaces appendString:stringToAdd];
    }

    return stringWithAddedSpaces;
}

Then to call it

[_answerTextField addTarget:self
                  action:@selector(reformatAsCardNumber:)
        forControlEvents:UIControlEventEditingChanged];

I need the pre-determined text such as __:__:__ or preferably __h:__m:__s so when you start typing you get 00h:0_m:__ as you fill out.

As right now, I get `` then when I start typing I get 00:0 etc..

Upvotes: 3

Views: 2457

Answers (1)

Daij-Djan
Daij-Djan

Reputation: 50109

Use the textFieldShouldChange method to modify the input / move the cursor as you see fit BEFORE it is updated on the screen

it is in UITextFieldDelegate:

textField:shouldChangeCharactersInRange:replacementString:
Asks the delegate if the specified text should be changed.
The text field calls this method whenever the user types a new character in the text field or deletes an existing character.


in addition there is also textDidChange in the delegate which works AFTER the text is shown


these are DELEGATE methods so you have to become the textField's delegate:

//1 conform to the delegate
@interface MyViewController <UITextFieldDelegate>

then

//2 set yourself as delegate (can also be done through IB)
textView.delegate = self;

Upvotes: 3

Related Questions