views:

784

answers:

3

For some reason, I'm having trouble with making a textfield the first responder.

I have a UITableView with two rows. Each row has a label and a UITextField. The textfields are tagged kLoginRowIndex = 0 and kPasswordRowIndex = 1. As you might have guessed, I use this for setting login and password.

If the user taps on the return button when editing the login textfield, I want the password textfield to get the focus. Unfortunately, the password textfield doesn't accept the focus. Here is my code:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSLog(@"%s:(textField.tag:%d)", __FUNCTION__, textField.tag);
    [textField resignFirstResponder];
    if(textField.tag == kLoginRowIndex) {
        UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:kPasswordRowIndex inSection:0]];
        UITextField *nextTextField = (UITextField *)[cell viewWithTag:kPasswordRowIndex];
        NSLog(@"(nextTextField.tag:%d)", nextTextField.tag);
        NSLog(@"canBecomeFirstResponder returned %d", [nextTextField canBecomeFirstResponder]);
        NSLog(@"becomeFirstResponder returned %d", [nextTextField becomeFirstResponder]);
    } else {
        [self validate:textField];
    }
    return NO;
}

This is the log output:

-[SettingsViewController textFieldShouldReturn:]:(textField.tag:0)
(nextTextField.tag:1)
canBecomeFirstResponder returned 1
becomeFirstResponder returned 0

What I tried:

  • returning YES instead of NO
  • removing the call to canBecomeFirstResponder (which is just for debugging purposes)

Any hints are appreciated!

A: 

It's been a while since I developed for the iPhone, and I have never used the tag that you show in your code. But you can do what you want by making the textfields properties of your class. If you do that, and let's say you name those properties loginTextField and passwordTextField, then you can let the next textField be focused as follows:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if([self usernameTextField] == textField) {
     return [[self passwordTextField] becomeFirstResponder];
    }
    else {
     // your validating code...
    }

    return NO;
}

But as I said, it's been a while and I don't know this tag-thing you talk about, so maybe it's some new best practice, but the above code should be working

tmadsen
Thanks! While not exactly what I was looking for, your answer helped to point me in the right direction.A tag can be used to identify view objects.http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/doc/uid/TP40006816-CH3-SW25
Daniel Hepper
+1  A: 

After playing with the suggestion of tmadsen, I found the error. The mistake is this line:

UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:k

It returns a new cell, not the one currently on the screen. I replaced it with

UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:kPasswordRowInde

and now it works as expected.

On a side note, I found out that 0 is the default value for the tag property, so it's probably not so clever to use it.

Daniel Hepper
A: 

0 is the default value for the tag property so you'll probably want to use something other than 0, otherwise you will most likely return the superview when you call viewWithTag:

jessecurry
You are right. It wasn't the problem with my code, but using 0 as tag is definitely not a good idea.
Daniel Hepper