未正确设置第一响应者
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 中正确呈现