Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In iOS 6, -[UITextField becomeFirstResponder] doesn't work in -viewWillAppear:

In iOS 5.1 and iOS 5.0 it works, but in iOS 6.0 the keyboard does not show.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    UITextField *textField = self.emailAddressTextField;
    [textField becomeFirstResponder];
}

For now I moved the logic to -viewDidAppear:.

// This works but is not desirable.
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    UITextField *textField = self.emailAddressTextField;
    [textField becomeFirstResponder];
}

This works, but is not desirable. The keyboard slide-up animation is shown after the view loads.

I want to keyboard to be present as the slide-to-left animation presents the view being loaded in the navigation controller.

Do anyone know how to have the keyboard loaded as the view appears in iOS 6?

update

Based on @Duck's feedback, I did a little more testing. This seems to be specific to UITextFields contained in UITableViewCells.

Does anyone have any suggestions?

FIRST SOLUTION

So a full description. This is a table view with two static cell (email and password). There is a login button in a view that is assigned the table footer view. The two cells have have a text field in them and are of a custom type SICOTextFieldCell.

My solution was to put a fake text field behind the login button (in the table footer view).

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    UITextField *textField = self.SICO_fakeTextField;
    [textField becomeFirstResponder];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    UITextField *textField = self.SICO_emailAddressTextField;
    [textField becomeFirstResponder];
}

NEW SOLUTION

Based on the answer by @stm, I came up with a new (superior?) solution.

My solution was to call -selectRowAtIndexPath:animated:scrollPosition:. -[SICOTextFieldCell setSelected:animated:], which is a custom table view cell, calls [self.textField becomeFirstResponder] which magically draws the keyboard correctly. It's still a hack, but it's a cleaner hack.

@interface SICOLogInViewController ()
@property (readonly, nonatomic) UITextField *SICO_emailAddressTextField;
@property (readonly, nonatomic) UITextField *SICO_passwordTextField;
@end

@implementation SICOLogInViewController

- (IBAction)logIn
{
    // Controller Details
}

#pragma mark Private

- (UITextField *)SICO_textFieldForRowAtIndexPath:(NSIndexPath *)indexPath
{
    SICOTextFieldCell *cell = (SICOTextFieldCell *)[self.tableView cellForRowAtIndexPath:indexPath];
    return cell.textField;
}

#pragma mark View lifecycle

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
                                animated:NO scrollPosition:UITableViewScrollPositionTop];
}

#pragma mark UITextFieldDelegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    switch (textField.returnKeyType) {
        case UIReturnKeyGo:   [self logIn];                                       break;
        case UIReturnKeyNext: [self.SICO_passwordTextField becomeFirstResponder]; break;
        default: break;
    }
    return YES;
}

#pragma mark Properties

- (UITextField *)SICO_emailAddressTextField
{
    return [self SICO_textFieldForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
}

- (UITextField *)SICO_passwordTextField
{
    return [self SICO_textFieldForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
}

@end
like image 849
Jeffery Thomas Avatar asked Nov 20 '12 18:11

Jeffery Thomas


2 Answers

Try calling it in the cellForRowAtIndexPath method after creating the cell, or in the viewWillAppear of the tableViewCell that contains that textField.

If that gives you the same result and you still want the keyboard to appear before, I would use a "fake" textField to display the keyboard in the beginning. My guess is that your textField hasn't been added before the viewWillAppear.

like image 132
k20 Avatar answered Nov 17 '22 05:11

k20


I tried your code exactly, iOS6 & in viewWillAppear and it seemed to work fine. Your trying to have the keyboard already displayed when you push over to a different view am i correct?

like image 2
agierens Avatar answered Nov 17 '22 04:11

agierens