Question

i have 6 textfields named digit1,digit2..etc upto digit6 added as a subview over a view. i want the digit2 textfield to autofocus once the user enters a digit in the digit1 textfield and similarly digit3 should autofocus when a digit is entered in digit2 textfield.Below shown is the code i tried.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range  replacementString:(NSString *)string
{
    if(textField.text.length>=1)
    {
        [textField resignFirstResponder];
        UITextField *_textField=(UITextField*) [self.view viewWithTag:textField.tag+1];
        [_textField becomeFirstResponder];
    }
    return TRUE;
} 

What happens here is when i enter a digit in digit1 it dosent appear in digit 1 but it appears in digit2 and also when i click delete button the control is transfered to the subsequent textfields rather than deleting the text in the current textfield.Please help me to fix this.

Was it helpful?

Solution 3

I found the solution

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

    NSString *str = [textField.text stringByReplacingCharactersInRange:range withString:string];
    if( [str length] > 0 ){
        textField.text = string;
        UIResponder* nextResponder = [textField.superview viewWithTag:(textField.tag + 1)];
        if (nextResponder) {
            [nextResponder becomeFirstResponder];
        }
        return NO;
    }    
    return YES;

} 

OTHER TIPS

lets assume that you have 3 textfields with names such as t1, t2 and t3

set tag value for t1 = 1, t2 = 3 and t3 = 3

set tag values for all the textfields and the write this code

then write this code

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

switch(textField.tag){
case 1:{
    if(textField.text.length>=1)
    {
        [t1 resignFirstResponder];
        [t2 becomeFirstResponder];
        break;
    }
    }

case 2:{
    if(textField.text.length>=1)
    {
        [t2 resignFirstResponder];
        [t3 becomeFirstResponder];
        break;
    }
    }
case 3:{
    if(textField.text.length>=1)
    {
        [t3 resignFirstResponder];

    break;
    }
    }
}
}
    return TRUE;
} 

I think the problem is that shouldChangeCharactersInRange gets called before the edit actually occurs. Since you are changing the first responder in there, the edit takes effect in the new first responder instead of the old one.

You could try moving the code inside your if block to another method, and calling it with [self performselector:withObject:afterDelay], setting the delay to some small value. Something like:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range  replacementString:(NSString *)string
{
    if(textField.text.length>=1)
    {
        [self performSelector:@selector(switchTextField) withObject:nil afterDelay:0.1];
    }
    return TRUE;
}


-(void)switchTextField
{
     [textField resignFirstResponder];
     UITextField *_textField=(UITextField*) [self.view viewWithTag:textField.tag+1];
     [_textField becomeFirstResponder];
}

That way shouldChangeCharactersInRange returns true immediately (as it should), the edit will take place in the currently selected textField, and then your switchTextField method will get called soon after. It's not the cleanest solution, but it's the quickest I can think of off the top of my head.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top