UITextField subview of UITableViewCell to become first responder?
Asked Answered
A

4

17

I have a core data application which uses a navigation controller to drill down to a detail view and then if you edit one of the rows of data in the detail view you get taken to an Edit View for the that single line, like in Apples CoreDataBooks example (except CoreDataBooks only uses a UITextField on its own, not one which is a subview of UITableViewCell like mine)!

The edit view is a UITableviewController which creates its table with a single section single row and a UITextfield in the cell, programatically.

What I want to happen is when you select a row to edit and the edit view is pushed onto the nav stack and the edit view is animated moving across the screen, I want the textfield to be selected as firstResponder so that the keyboard is already showing as the view moves across the screen to take position. Like in the Contacts app or in the CoreDataBooks App.

I currently have the following code in my app which causes the view to load and then you see the keyboard appear (which isn't what I want, I want the keyboard to already be there)

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [theTextField becomeFirstResponder];
}

You can't put this in -viewWillAppear as the textfield hasn't been created yet so theTextField is nil. In the CoreDataBooks App where they achieve what i want they load their view from a nib so they use the same code but in -viewWillAppear as the textfield has already been created!

Is there anyway of getting around this without creating a nib, I want to keep the implementation programatic to enable greater flexibility.

Many Thanks

Angelita answered 17/4, 2010 at 12:0 Comment(0)
A
16

After speaking with the Apple Dev Support Team, I have an answer!

What you need to do is to create an offscreen UITextField in -(void)loadView; and then set it as first responder then on the viewDidLoad method you can set the UITextField in the UITableViewCell to be first responder. Heres some example code (remember I'm doing this in a UITableViewController so I am creating the tableview as well!

- (void)loadView
{
    [super loadView];

    //Set the view up.
    UIView *theView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.view = theView;
    [theView release];

    //Create an negatively sized or offscreen textfield
    UITextField *hiddenField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, -10, -10)];
    hiddenTextField = hiddenField;
    [self.view addSubview:hiddenTextField];
    [hiddenField release];

    //Create the tableview
    UITableView *theTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds] style:UITableViewStyleGrouped];
    theTableView.delegate = self;
    theTableView.dataSource = self;
    [self.view addSubview:theTableView];
    [theTableView release];

    //Set the hiddenTextField to become first responder
    [hiddenTextField becomeFirstResponder];

    //Background for a grouped tableview
    self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    //Now the the UITableViewCells UITextField has loaded you can set that as first responder
    [theTextField becomeFirstResponder];
}

I hope this helps anyone stuck in the same position as me!

If anyone else can see a better way to do this please say.

Angelita answered 22/4, 2010 at 14:36 Comment(5)
I've battled with this for over a year. Sometimes I'd get a solution that would work, but then a new update to iOS would break it. So annoying. This is the best solution I've seen to date, despite how hacky it feels.Clothbound
Thank you for this great hack but I don't understand why we need 'hiddenTextField'? Do 'hiddenTextField' and 'theTextField' point to the same UITextField instance?Hectocotylus
when you use this "hack", can you see the cursor? I've tried with a custom uitableviewcell with a uitextview in it: the keyboard opens but there isn't the focus on the uitextview.Sheepshearing
I have used this, but I didn't use negative frame and I didn't put a textField on a view before adding it on UITableViewCell. Also, I didn't have to make it first responder in loadView. It worked by creating a UITextField object in loadView and making it first responder in ViewDidAppear.Blackboard
@wzbozon can you elaborate a bit more? Your solution sounds a bit better.Frederic
V
5

Try do it in viewDidAppear method, works for me.

Viccora answered 3/9, 2011 at 8:10 Comment(0)
E
3

I think the obvious solution is to create the textfield in the init method of the view controller. That is usually where you configure the view because a view controller does require a populated view property.

Then you can set the textfield as first responder in viewWillAppear and the keyboard should be visible as the view slides in.

Euchre answered 17/4, 2010 at 13:44 Comment(3)
I currently create the UITextField in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath along with the cell. I initialised the UITextField in the init method and putting becomeFirstResponder in viewWillApper worked but the Keyboard still did not slide in it just appeared once the view had slid in. Which i can't understand!?!Angelita
No, you need to create a new text filed in the detail view and set that as the first responder. If you set that before the view actually appears it should appear with the keyboard already in view. You can't transfer the first responder of one view to another view pushed on the nav stack. The first responder of the table won't have any effect on the first responder of the nav view regardless of how it appears to the user.Euchre
The detailview is the view the user is currently looking at before they tap a row to take them to the edit view which has the text field on it. I'm not sure if I understand how putting a a textfield with firstresponder on a view which is about to "disappear" will make a keyboard appear on the view about to "appear"? The reason why I think this doesn't work is because the tableview isn't created until the view appears thus you can't select first responder on the current text field before the view comes in as it hasn't been created yet! But then Apple seem to do it in the Contacts App some howAngelita
W
2

have you tried using the uinavigationcontroller delegate methods?:

navigationController:willShowViewController:animated:

Woald answered 18/4, 2010 at 22:21 Comment(1)
Hi remover thanks for your reply! I have just tried it and it didn't work again UITextField is nil at the time which navigationController:willShowViewController:animated: is called I believe for the same reasons as above. Unless there is away of creating the textfield in the table before the view is loaded I guess the only way must to be to do it from a nib!Angelita

© 2022 - 2024 — McMap. All rights reserved.