Question

I'm trying to create blood pressure app with simple controls to add results. To make it simpler I decided that when user types 3 characters in systolic pressure, then app should move cursor (and first responder) to diastolic value, and then to pulse. So I made it in this way:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if ([self systolicValue].isFirstResponder && [self systolicValue].text.length == 3) {
        [[self diastolicValue] becomeFirstResponder];
    }
    else if ([self diastolicValue].isFirstResponder && [self diastolicValue].text.length == 2) {
        [[self pulseValue] becomeFirstResponder];
    }
    else if ([self pulseValue].isFirstResponder && [self pulseValue].text.length == 2) {
        [[self pulseValue] resignFirstResponder];
    }
    return YES;
}

I believe it's good solution, but doesn't work in way I want to. Three numbers in systolicValue doesn't make diastolicValue first responder immediately. First user has to press another number and then cursor is moved to next text field and number goes here. It's a little bit inconvenient, because user has no clue that cursor moves automatically after three numbers.

Any idea how focus next text field immediately? I tried also [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldTextDidChange:) name:UITextFieldTextDidChangeNotification object:nil]; in viewDidLoad(), and method similar to the one above (but without return of course, because it's void), but it doesn't work either. In fact it doesn't work at all, and after first number makes this:

2013-08-07 08:39:09.805 MyApp[973:c07] -[AddViewController textFieldTextDidChange:]: unrecognized selector sent to instance 0x7580000
2013-08-07 08:39:09.809 MyApp[973:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AddViewController textFieldTextDidChange:]: unrecognized selector sent to instance 0x7580000'
*** First throw call stack:
(0x1c92012 0x10cfe7e 0x1d1d4bd 0x1c81bbc 0x1c8194e 0xb904f9 0x1cec0c5 0x1c46efa 0xac4bb2 0xad7e6b 0xe5174 0xef5a6 0xb904f9 0x1cec0c5 0x1c46efa 0xac4bb2 0x35689de 0x26b61da 0x2aefdfc 0x2af2bf8 0x3543612 0x354374a 0x3543ec0 0x3543cb8 0x3543204 0x293122b 0x2931193 0x3515e96 0x35424cc 0x2aed136 0x2aec3c6 0x2b1f980 0x317b7fd 0x2b16576 0x2b176da 0x2b1572e 0x3179eaa 0x2b2faf1 0x2b1f72a 0x2af36ae 0x26f262b 0x10e36b0 0x355e810 0x27311a4 0x27332ff 0x1d50b4 0x197aef 0x198e58 0x1979fe 0x1a1d29 0x24ddb 0x1227f5 0x1227f5 0x1227f5 0x1227f5 0x1227f5 0x1227f5 0x1227f5 0x1227f5 0x24e35 0x24806 0x24beb 0x16698 0x1beddf9 0x1bedad0 0x1c07bf5 0x1c07962 0x1c38bb6 0x1c37f44 0x1c37e1b 0x1bec7e3 0x1bec668 0x13ffc 0x1f2d 0x1e55 0x1)
libc++abi.dylib: terminate called throwing an exception
(lldb) 
Was it helpful?

Solution

Try doing something like this :

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string  // return NO to not change text
{

    NSMutableString *finalString = [[NSMutableString alloc] initWithString:textField.text];
    [finalString replaceCharactersInRange:range withString:string];


    if ([self systolicValue].isFirstResponder && [self systolicValue].text.length == 3))
    {
        [[self systolicValue] setText:finalString];
        [[self systolicValue] resignFirstResponder];
        return NO;
    }

    return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField          // may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
{
    [[self diastolicValue] becomeFirstResponder];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top