未正确设置第一响应者

Posted

技术标签:

【中文标题】未正确设置第一响应者【英文标题】:first responder is not being set correctly 【发布时间】:2013-04-16 16:04:11 【问题描述】:

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

这对我来说并不是什么新鲜事,我的代码在我进行一些不相关的更改之前可以正常工作,而现在却不行。当我设置它的第一响应者时,我有一个指向正确文本字段的指针,没有任何反应。

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

代码如下:

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

【问题讨论】:

什么是焦点?如果“什么都没发生”,你如何摆脱“专注”?您是否有没有“不相关更改”的先前版本来检查同一设备/模拟器? 我的猜测是这个问题根本与这段代码无关。检查文本字段 (ObjectEditField) 代码中发生的情况。也许当becomeFirstResponder 被调用时它正在做某事?也许它阻塞了主线程?也许在这之间发生了其他事情,其他一些领域成为第一响应者? 它在模态视图控制器内吗? @Sulthan 是的,这是在模态视图控制器中 @A-Live by focus 我的意思是当你有一个文本字段处于焦点时,你会在字段内看到闪烁的线,如果你输入,字符就会出现在那里。这显示了“专注”。当我分配FirstResponder 时,它会远离当前文本字段(应该如此),但焦点从未在新文本字段中设置 【参考方案1】:

首先,我绝对会验证您上面的描述,即您的代码“之前有效”并且更改是“不相关的”。根据定义,您对工作代码所做的任何更改都会在某种程度上导致它不再工作。如果不是直接的,那么由于副作用而间接地。

从您发布的代码示例中,所有让我印象深刻的是以下行:

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

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

    您向其发送becomeFirstResponder 的 textField 与单元格中实际的 textField 实例不同。

    当您调用 becomeFirstResponder 时,尚未创建单元格,因为动画滚动带有 textField 的单元格进入视图。

我会取消您为返回工作版本所做的任何更改,并真正确保在预期时间发送正确的 textField becomeFirstResponder

【讨论】:

唯一改变的是这个文件将数据保存到字典而不是对象。没有其他任何改变。在我正在测试的当前情况下,我试图将第一响应者设置为的单元格实际上仍然可见,并且没有发生滚动。 (它们是相邻的两行)而且我同意有些事情必须改变。我只是不知道是什么,因为唯一真正改变的是数据的保存位置。【参考方案2】:

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

首先解释一下 - 默认情况下,如果模态控制器中的文本字段失去焦点,则键盘不会隐藏。这是由方法-[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 中发出警告。

解决方案:

    清理您的代码,检查警告。 在becomeFirstResponder 调用之前添加NSLog(@"%@", textField.field)。检查日志。

【讨论】:

以上是关于未正确设置第一响应者的主要内容,如果未能解决你的问题,请参考以下文章

词袋未正确标记响应

NX 许可证错误:许可证服务器关机或未响应。检查UGS_LICENSE_SERVER设置是不是正确。[-96]这个问题怎么解决

如何正确地将 UITextField 设为第一响应者? (尝试了3种方法)

jquery 事件按钮显示正确的响应,但视图未在 django 中正确呈现

UITableViewCell 中的 UITextView:第一响应者问题

RestKit 响应未正确映射