我有一个分组表视图,并试图在用户按回车键时为文本字段设置一个新的第一响应者。
这对我来说不是什么新鲜事,在我做一些不相关的更改之前,我的代码工作了,现在它不工作了。我有一个指向正确文本字段的指针当我设置它的第一个响应者时,什么也没发生。
焦点完全远离任何文本字段,键盘留在屏幕上。然后回车键和"隐藏键盘"键都停止工作,直到用户重新开始关注文本字段。
代码如下:
- (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的单元格滚动到视图中。一种可能性是,单元格是在滚动到视图中时创建的,这取决于代码的其余部分,可能会导致以下问题:
发送
becomeFirstResponder
的textField与单元格中实际的textField实例不同。单元格还没有创建,当你调用
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中的大多数代码都应该发出警告。
解决方案:
- 清理代码,检查警告。
- 在
becomeFirstResponder
呼叫前放一个NSLog(@"%@", textField.field)
。查看日志