0

After a UITextField is edited and return is pressed, I loop through and check for the next field. I get the index path of that field, then save it. Next I reload table data and when the table is being built, if the indexPath is equal to the indexPath of what would be the next text field, then I set it as first responder.

I grab the correct textField at the correct indexPath and everything, however first responder doesn't get set. Instead, focus just disappears.

My code:

//inside UITextFieldShouldReturn

for (int i = uiTextField.fieldTag + 1; i < group.fields.count; i++) {
ObjectEditField *field = [group.fields objectAtIndex:i];
     if (field.propName && field.updateObjectOnEdit == YES && [field isKindOfClass:[ObjectEditTextField class]]) {
        // set the active field
        activeField = field;

       // obtain a pointer to the textfield object and set it to be the first responder
         ObjectEditTextField *textField = (ObjectEditTextField *)field;
         if (![textField.field isFirstResponder]) {
         UITableViewCell *cell = (UITableViewCell *)[[[uiTextField superview] superview] superview];
         firstResponderIndexPath = [_fieldsTableView indexPathForCell:cell];

Then once I have the firstResponderIndexPath I call reloadData on the table view, and inside tableView:cellForRowAtIndexPath: I have:

if (firstResponderIndexPath.row + 1 == indexPath.row)
{
    ObjectEditTextField *textField = (ObjectEditTextField *)field;
    NSLog(@"display: %@", textField.field.text);
    [textField.field becomeFirstResponder];
}

The output for the NSLog is correct and the field it should be. However the first responder doesn't get set correctly.

Monolo
  • 18,205
  • 17
  • 69
  • 103
JMD
  • 1,540
  • 2
  • 24
  • 56

2 Answers2

1

You can only set the first responder if the view is part of the view hierarchy of the window. "tableView:cellForRowAtIndexPath:" gets called before it is added. So you'll have to set the first responder after the cells have been added, e.g. after you call reloadData in your UITableViewController subclass:

[self.tableView reloadData];
MyTableCell *cell = (id)[self.tableView cellForRowAtIndexPath: firstResponderIndexPath];
[cell.myTextFieldProperty becomeFirstResponder];
lassej
  • 6,256
  • 6
  • 26
  • 34
0

Has the cell been added to the window at the point where you are calling becomeFirstResponder? If it is not, nothing will happen. From the docs:

becomeFirstResponder

You may call this method to make a responder object such as a view the first responder. However, you should only call it on that view if it is part of a view hierarchy. If the view’s window property holds a UIWindow object, it has been installed in a view hierarchy; if it returns nil, the view is detached from any hierarchy.

Try calling it in tableView:willDisplayCell:forRowAtIndexPath: instead. You could also set a boolean property on the desired cell and have it call becomeFirstResponder on its field in didMoveToSuperview.

jszumski
  • 7,430
  • 11
  • 40
  • 53
  • I moved my if check to the method you mentioned but no dice. same effect is happening. – JMD Apr 26 '13 at 19:38
  • Did you try using the cell's `didMoveToSuperview`? – jszumski Apr 26 '13 at 19:39
  • how do you use a cell's didMoveToSuperview? – JMD Apr 26 '13 at 19:42
  • Implement `didMoveToSuperview` in a custom `UITableViewCell` subclass and add two properties: something like `BOOL shouldAutomaticallyBecomeFirstResponder` and `UITextField inputField. In `didMoveToSuperview`, check if that property is `YES` then call `becomeFirstResponder` on `inputField`. – jszumski Apr 26 '13 at 19:46
  • just implemented this. no change. didMoveToSuperView never gets called after a user submits to a textfield. only when the cells display for the first time. – JMD Apr 26 '13 at 20:06