Search code examples
delegateskeyboarduitextfield

UITextField, automatically move to next after 1 character


Scenario: I have 4 UITextFields that only accept 1 character. Easy.

Problem: After I enter the 1 character, I want the next TextField to become active automatically without having to press next (i.e. I'm using the UIKeyboardTypeNumberPad, and theres no NEXT button. (I KNOW I can actually create a next button programmatically, but I dont want to go that far, just need the next field to become active automatically after the 1 character is entered.

#define MAX_LENGTH 1

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    for (int i = 0; i < [string length]; i++) {
    unichar c = [string characterAtIndex:i];
        if (![myCharSet characterIsMember:c]) {
            return NO;
        }
    }
        NSUInteger newLength = [textField.text length] + [string length] - range.length;
        return (newLength > 1) ? NO : YES;
}


-(BOOL)textFieldShouldReturn:(UITextField *)textField {
    if (textField == pc1) {
        [pc2 becomeFirstResponder];
    }else if (textField == pc2) {
        [pc3 becomeFirstResponder];
    }else if (textField == pc3) {
        [pc4 becomeFirstResponder];
    }else if (textField == pc4) {
        [textField resignFirstResponder];
    }
    return YES;
}

Solution

  • I arrived at a solution by modifying some code I found here: http://www.thepensiveprogrammer.com/2010/03/customizing-uitextfield-formatting-for.html

    First set the your view controller to be the delegate of the textfields.

    Then do something like this:

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {   
        BOOL shouldProcess = NO; //default to reject
        BOOL shouldMoveToNextField = NO; //default to remaining on the current field
    
        int insertStringLength = [string length];
        if(insertStringLength == 0){ //backspace
            shouldProcess = YES; //Process if the backspace character was pressed
        }
        else {
            if([[textField text] length] == 0) {
                shouldProcess = YES; //Process if there is only 1 character right now
            }
        }
    
        //here we deal with the UITextField on our own
        if(shouldProcess){
            //grab a mutable copy of what's currently in the UITextField
            NSMutableString* mstring = [[textField text] mutableCopy];
            if([mstring length] == 0){
                //nothing in the field yet so append the replacement string
                [mstring appendString:string];
    
                shouldMoveToNextField = YES;
            }
            else{
                //adding a char or deleting?
                if(insertStringLength > 0){
                    [mstring insertString:string atIndex:range.location];
                }
                else {
                    //delete case - the length of replacement string is zero for a delete
                    [mstring deleteCharactersInRange:range];
                }
            }
    
            //set the text now
            [textField setText:mstring];
    
            [mstring release];
    
            if (shouldMoveToNextField) {
                //
                //MOVE TO NEXT INPUT FIELD HERE
                //
            }
        }
    
        //always return no since we are manually changing the text field
        return NO;
    }