第一响应者设置不正确



我有一个分组表视图,并试图在用户按回车键时为文本字段设置一个新的第一响应者。

这对我来说不是什么新鲜事,在我做一些不相关的更改之前,我的代码工作了,现在它不工作了。我有一个指向正确文本字段的指针当我设置它的第一个响应者时,什么也没发生。

焦点完全远离任何文本字段,键盘留在屏幕上。然后回车键和"隐藏键盘"键都停止工作,直到用户重新开始关注文本字段。

代码如下:

- (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;
            }
        }
    }

首先,我绝对会验证你上面的描述,你的代码"以前工作过"和更改是"无关的"。根据定义,您对工作代码所做的任何更改都会以某种方式导致它不再工作。如果不是直接的,那就是间接的。

从你发布的代码示例中跳出来的是这行:

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

您正在做正确的事情,确保包含textField的单元格滚动到视图中。一种可能性是,单元格是在滚动到视图中时创建的,这取决于代码的其余部分,可能会导致以下问题:

  1. 发送becomeFirstResponder的textField与单元格中实际的textField实例不同。

  2. 单元格还没有创建,当你调用becomeFirstResponder由于动画滚动单元格与textField进入视图。

我会退出你所做的任何更改,回到一个工作版本,并真正确保正确的textField正在发送becomeFirstResponder在预期的时间。

通过注释,该字段位于模态(呈现)控制器内。

首先解释一下——默认情况下,如果模态控制器中的文本字段失去焦点,键盘不会被隐藏。这是由-[UIViewController disablesAutomaticKeyboardDismissal]方法控制的

当视图控制器的模态呈现样式被设置为UIModalPresentationFormSheet时,这个方法的默认实现返回YES,对于其他的呈现样式返回NO。因此,系统通常不允许在模态表单中忽略键盘。

这解释了为什么键盘的行为方式。没有文本框被聚焦,键盘也没有被隐藏,这仅仅是因为我们在模态控制器中。

那么,发生了什么?我们知道当前的文本字段放弃了第一响应者,要么没有视图成为第一响应者,要么不可编辑的视图成为第一响应者。

嗯,你的整个代码看起来很可疑:

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

这里有一个类型为ObjectEditField的对象

[field isKindOfClass:[UITextField class]]

现在,我们正在测试,如果字段是UITextField的子类。这很可疑。如果是ObjectEditField,怎么会也是UITextField呢?

让我们继续

UITextField *textField = (UITextField *)field;

好的,我们假设它是UITextField

if (![textField.field isFirstResponder]) {

再一次,某事非常可疑。UITextField没有field属性。

:

[textField.field becomeFirstResponder];

在未知对象上调用。我们甚至不知道它是否是UITextField

请注意,IDE中的大多数代码都应该发出警告。

解决方案:

  1. 清理代码,检查警告。
  2. becomeFirstResponder呼叫前放一个NSLog(@"%@", textField.field)。查看日志

最新更新