resignFirstResponder 没有在 textFieldShouldClear 中被调用

Posted

技术标签:

【中文标题】resignFirstResponder 没有在 textFieldShouldClear 中被调用【英文标题】:resignFirstResponder not getting called inside textFieldShouldClear 【发布时间】:2014-07-26 08:33:46 【问题描述】:

我正在尝试在我的一个页面中实现搜索栏。

由于它的设计,我没有使用常规搜索栏。

我所拥有的如下。

UIImageView above UIView (textfield background)
UITextField above UIImageView (textfield)

我将delegates 用于UITextField

在代码中我有searchTF.clearButtonMode = UITextFieldViewModeWhileEditing; 来显示清除按钮。

搜索工作正常,但问题出在清除按钮的委托上。

我有以下代码

- (BOOL)textFieldShouldClear:(UITextField *)textField

    if (textField == searchTF) 

        NSLog(@"clicked clear button");
        [textField resignFirstResponder]; // this is not working
        // also below is not working
        // [searchTF resignFirstResponder];
    

    return YES;

当我点击清除按钮时,我得到文本“点击清除按钮”的 NSLog,但是键盘没有被关闭。

知道为什么我有键盘时没有被解雇


编辑 1

即使我尝试如下使用[self.view endEditing:YES];,但仍然无法正常工作。

- (BOOL)textFieldShouldClear:(UITextField *)textField

    if (textField == searchTF) 
        [self.view endEditing:YES];
        [self hideAllKeyboards];
    
    return YES;

【问题讨论】:

@downvoter : 请评论否决... 【参考方案1】:

除了我的评论之外,我还做了一些测试,以下是我的结果:

我刚刚实现了一个UITextField,所有委托方法都像这样:

- (BOOL)textFieldShouldClear:(UITextField *)textField 
  NSLog(@"Should Clear");
  [textField resignFirstResponder];
  return YES;


- (void)textFieldDidBeginEditing:(UITextField *)textField 
  NSLog(@"Begin editing");


- (void)textFieldDidEndEditing:(UITextField *)textField 
  NSLog(@"End editing");


- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField 
  NSLog(@"Should begin editing");
  return YES;


- (BOOL)textFieldShouldEndEditing:(UITextField *)textField 
  NSLog(@"Should end editing");
  return YES;


- (BOOL)textField:(UITextField *)textField
    shouldChangeCharactersInRange:(NSRange)range
                replacementString:(NSString *)string 
  NSLog(@"Change char");
  return YES;

点击清除按钮后,日志输出:

2014-07-26 11:08:44.558 Test[36330:60b] Should Clear
2014-07-26 11:08:44.558 Test[36330:60b] Should end editing
2014-07-26 11:08:44.559 Test[36330:60b] End editing
2014-07-26 11:08:44.560 Test[36330:60b] Should begin editing
2014-07-26 11:08:44.561 Test[36330:60b] Begin editing

如您所见,shouldBeginEditingdidBeginEditing 方法在清除后被调用,因此 textFieldshouldClear 中的 resignFirstRespondershouldBeginEditingdidBeginEditing 调用新的 becomeFirstResponder 之前被调用。

【讨论】:

+1 :详细解释...现在我明白发生了什么...感谢您说清楚... Mh 我认为您解决问题的方式更像是一种解决方法,因为您的计时器可能比委托方法更快,例如在较慢的设备上。更好的解决方案是像这样实现textFieldShouldClear [textField resignFirstResponder]; textField.text = @""; return NO; textFieldShouldClear[textField resignFirstResponder];。那是个大问题..这就是我选择NSTimer 的原因 @FahimParkar 是的,但你没有返回NO,这就是区别!仔细看我的评论【参考方案2】:

我相信您的文本字段 IBOutlet 已正确连接,尽管您可以尝试

[[[UIApplication sharedApplication] keyWindow] endEditing:YES];

【讨论】:

【参考方案3】:

我不确定是什么问题但我解决了使用NSTimer 在一段时间后调用解除键盘方法的问题。

以下是我所做的。

- (BOOL)textFieldShouldClear:(UITextField *)textField

    if (textField == searchTF) 
        [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(hideAllKeyboards) userInfo:nil repeats:NO];
    
    return YES;


-(void) hideAllKeyboards 
    [searchTF resignFirstResponder];

这样,在单击清除按钮后,键盘将被关闭。

如果有人回答为什么会发生这种情况,那就太好了。我会将该答案标记为已接受。


编辑 1

根据丹尼尔的回答,我在下面做了。

- (BOOL)textFieldShouldClear:(UITextField *)textField

    if (textField == searchTF) 
        isFilterOn.text = @"no";
        [textField resignFirstResponder];
        textField.text = @"";
        [self myTextFieldDidChange];
    

    return NO;

myTextFieldDidChange 中,我根据UITextField 中的文本显示过滤列表和未过滤列表。

【讨论】:

我认为这是因为textFieldShouldClear - 方法确实调用了textFieldDidBeginEditing,因为清除也是一种编辑。因此textFieldDidBeginEditing 正在触发becomeFirstResponder,并且键盘不会被关闭。您可以通过实现UITextField 的所有委托方法并设置一些断点来测试这一点。 只需使用 [self.view endEditing:YES] 隐藏您的键盘 @NitinGohel :已经这样做了,仍然没有工作......我已经更新了同样的问题......检查丹尼尔的答案......

以上是关于resignFirstResponder 没有在 textFieldShouldClear 中被调用的主要内容,如果未能解决你的问题,请参考以下文章

resignFirstResponder 没有按预期工作

没有看到 UIScrollView 上的 UITextField 时 resignFirstResponder

resignFirstResponder 没有按预期工作。每次按键时键盘都会弹出,而不是仅返回

resignFirstResponder 不关闭键盘

为啥必须在主队列上异步调用 resignFirstResponder() 来关闭键盘

UITextField - resignFirstResponder 查询