first responder is not being set correctly

匿名 (未验证) 提交于 2019-12-03 02:42:02

问题:

I have a grouped table view and trying to set a new first responder to a text field when the user hits enter.

This is nothing new to me, and my code worked before I made some unrelated changes and now it doesn't. I have a pointer to the correct text field when I set its first responder, nothing happens.

Focus goes away entirely from any text field and the keyboard stays on screen. Then both the enter and 'hide keyboard' keys stop functioning until the user re-initiates focus on a text field again.

Here is the code:

- (void)uiTextFieldShouldReturn:(ObjectEditTextField *)uiTextField  {         if ((group.fields.count - 1) > uiTextField.fieldTag)          {         //loop through every table group         for (int i = uiTextField.fieldTag + 1; i < group.fields.count; i++) {              //get whatever field is in the row (not necessarily a text field)              ObjectEditField *field = [group.fields objectAtIndex:i];              // a check if the field is of type UITextField             if (field.propName && field.updateObjectOnEdit == YES && [field isKindOfClass:[UITextField class]]) {                 // set the active field                 activeField = field;                  // adjust the table view offset to make sure the text field is visble                 [self setTableViewOffsetForTextField:field];                  // obtain a pointer to the textfield object and set it to be the first responder                 UITextField *textField = (UITextField *)field;                 NSLog(@"field %@", textField.fieldLabel);                 if (![textField.field isFirstResponder]) {                      [textField.field becomeFirstResponder];                     return;                  }                 break;             }         }     } 

回答1:

First off, I would absolutely verify that your description above that your code "worked before" and the changes are "unrelated". Any changes you made to working code, by definition, in some way contributed to it not working any longer. If not directly, then indirectly due to a side effect.

All that jumps out at me from your posted code sample is the line:

// adjust the table view offset to make sure the text field is visble [self setTableViewOffsetForTextField:field]; 

You are doing the right thing ensuring that that the cell containing the textField is scrolled into view. One possibility is that the cell is created when you scroll it into view which, depending on the rest of your code, may cause issues such as:

  1. the textField you are sending becomeFirstResponder to is a different instance than the textField actually in the cell.

  2. the cell hasn't been created yet when you call becomeFirstResponder due to animating scrolling the cell with the textField into view.

I would back out any changes you made to go back to a working version and really ensure the correct textField is being sent becomeFirstResponder at an expected time.



回答2:

By comments, the field is inside a modal (presented) controller.

First an explanation - by default, if a text field in a modal controller loses focus, the keyboard is not hidden. This is controlled by method -[UIViewController disablesAutomaticKeyboardDismissal]

The default implementation of this method returns YES when the modal presentation style of the view controller is set to UIModalPresentationFormSheet and returns NO for other presentation styles. Thus, the system normally does not allow the keyboard to be dismissed for modal forms.

This explains why the keyboard behaves the way it behaves. No text field is focused and the keyboard is not hidden only because we are inside a modal controller.

So, what happens? We know that the current text field resigns first responder and either no view becomes first responder or a non-editable view becomes first responder.

Well, you whole code looks very suspicious:

ObjectEditField *field = [group.fields objectAtIndex:i]; 

Here we have an object of type ObjectEditField

[field isKindOfClass:[UITextField class]] 

Now, we are testing, if the field is a subclass of UITextField. That's very suspicious. If it's ObjectEditField, how it can be UITextField, too?

Let's continue

UITextField *textField = (UITextField *)field; 

Okey, let's assume it's a UITextField

if (![textField.field isFirstResponder]) { 

Again, something very suspicious. A UITextField has no field property.

So:

[textField.field becomeFirstResponder]; 

is called on an unknown object. We don't even know if it's a UITextField.

Note that most of the code should issue warnings in your IDE.

Solution:

  1. Clean up your code, check warnings.
  2. Put a NSLog(@"%@", textField.field) before the becomeFirstResponder call. Check the log.


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!