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.