为啥 textFieldDidEndEditing: 没有被调用?

Posted

技术标签:

【中文标题】为啥 textFieldDidEndEditing: 没有被调用?【英文标题】:Why is textFieldDidEndEditing: not being called?为什么 textFieldDidEndEditing: 没有被调用? 【发布时间】:2009-08-04 15:48:17 【问题描述】:

我有一个 UITextField,当在其中输入文本时,我想从文本字段中获取 doubleValue 并执行一些计算并将它们显示在 UITableView 中。

UITextField 的委托采用 UITextFieldDelegate 协议,并实现了 textFieldShouldReturn: 和 textFieldDidEndEditing: 方法。 textFieldShouldReturn: 辞去第一响应者状态,根据文档也应该触发 textFieldDidEndEditing:,但我从未见过 textFieldDidEndEditing: 调用。

- (BOOL)textFieldShouldReturn:(UITextField*)theTextField 
    if (theTextField == thresholdValue) 
        [thresholdValue resignFirstResponder];
    
    return YES;


- (void)textFieldDidEndEditing:(UITextField *)textField 
    [self updateThresholdValue:textField];

值得注意的是,我还尝试将一些文本字段事件连接到委托并让事件调用 updateThresholdValue: 直接,但这也不起作用。

【问题讨论】:

放置一些 NSLogs 以确保该方法实际上从未被调用。 我假设他的代表已正确连接,否则 textFieldShouldReturn: 也不会被调用。 但我同意您的第一条评论 - 您是否尝试过 NSLog 或设置断点以确认未调用委托?会不会是它正在被调用,但 [self updateThresholdValue:textField]; 没有按照您的预期执行? 我没用过 NSLog();我在 textFieldDidEndEditing: 的实现中设置了一个断点,它没有被触发。 textFieldShouldReturn: 中的类似断点会触发。 关于 field.delegate = self...不,我没有这样做。委托是 UIViewController 的子类,它控制文本字段所在的视图。我发誓我昨晚读到 UITextFields 不能是他们自己的代表。等等……我明白你在说什么。您想知道我是否连接了文本字段的代表。是的。这是在 IB 中完成的,正如 Luke 所指出的,正在调用 textFieldShouldReturn: 的事实似乎表明委托已正确设置。 【参考方案1】:

刚刚遇到了你描述的同样的问题。在尝试了我能想到的一切之后,我添加了这个委托方法:

// if we encounter a newline character return
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
   
    // enter closes the keyboard
    if ([string isEqualToString:@"\n"])
    
        [textField resignFirstResponder];
        return NO;
    
    return YES;

现在 textFieldShouldEndEditing 触发并且文本字段退出第一响应者。

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField

    [textField resignFirstResponder];
    return YES;

【讨论】:

现在考虑在同一个 VC 上有两个 UITextField 的情况。在进入时退出 kbd 是个好主意吗?【参考方案2】:

textFieldDidEndEditing 在文本字段退出其第一响应者状态时触发,而 textFieldShouldReturn 在按下返回按钮时触发。

听起来就像您的文本字段永远不会辞去 firstResponder 的职务。您可以通过放置一些调试输出(如 cmets 中的建议)并通过触摸导航出文本字段来非常轻松地检查它 - 例如,开始输入然后只需触摸字段外部以强制它退出 firstResponder。

不确定这是否有很大帮助,但这听起来像是您遇到的一个奇怪案例。

【讨论】:

感谢您的来信。看看我添加到初始问题中的代码。 testFieldShouldReturn:确实调用了resignFirstResponder,并且我已经确认代码的辞职行是通过调试器执行的。 textFieldDidEndEditing: 作为 resignFirstResponder 执行的一部分被调用,还是在 resignFirstResponder 完成执行之后发生?最后,以防万一,我仍然在模拟器而不是实际设备中运行。我还没有魔法钥匙。 有关此的更多信息...我推出了 HelloWorld 演示应用程序——有一个文本字段、按钮和标签:在字段中键入文本、点击按钮、标签更新。我修改了笔尖,以便标签将“Editing Did End”事件发送到按钮使用的相同对象和操作。它奏效了。所以,我回到上面描述的我的应用程序并做了同样的事情......但它没有工作。肯定有什么微妙的不同,但到目前为止我还没有发现。 我要检查的另一件事是 textFieldDidEndEditing exactly 的方法签名与 api 文档中的签名匹配,它看起来对我来说是正确的,但如果有任何错误委托方法永远不会被调用。您实际上可以直接从 API 文档中复制签名以确保。 保罗的好建议。不幸的是,我已经尝试过了,但无济于事。请参阅我即将添加的后续答案。【参考方案3】:

如果你在你的视图控制器中采用了UITextFieldDelegate协议,那么在viewDidLoad方法中编写如下代码行来激活上述协议的方法到你对应的textFields:

override func viewDidLoad() 
    //other stuff
    yourTextField.delegate = self

【讨论】:

【参考方案4】:

正如其中一个 cmets 所述,我尝试使用 HelloWorld 应用程序复制一个更简单的版本,并且它在第一次尝试时就可以正常工作,没有任何问题,正如预期的那样。面对这种情况,我开始有点疑惑了。

在我试图找到这个问题的答案的所有谷歌搜索中,我遇到了一个链接,在该链接中,有人遇到了无法从按钮触发的事件的问题,结果发现问题与放置按钮的视图以及该视图具有另一个子视图作为按钮的对等视图,并且该子视图以某种方式吞噬了事件,而不是允许它们去往他们被引导的地方。情景与我的并不完全相同,但听起来足够接近,值得调查。尽管在这里收到了所有出色的建议,但还没有一个结果。

昨晚我决定从头开始完全重新创建 nib 文件(复制我最初拥有的文件),然后我让它工作了。关键的区别似乎是我在原始的非工作 nib 文件中,我从调色板中拖了一个TableViewController,然后将其类型更改为我的子类PZTableViewController。当我在我的新笔尖上做同样的事情时,事件并没有触发。另一方面,如果我删除了拖过的TableViewController,而只是拖过NSObject,并将其类更改为PZTableViewController,然后将所有内容都进行了探测,这一切都“正常工作”。

我将尝试寻找让我开始思考这一思路的链接,并将其作为编辑或评论发布。

这也不是一个完整的答案,因为我还不明白来自调色板的TableViewController 和我的子类之间的区别。当我弄清楚这一点时,我将通过编辑或评论来更新这个答案。

【讨论】:

【参考方案5】:

我最终连接了 editingChanged 来记录对文本字段的每一次更改,而不是弄清楚如何用剩余的回调覆盖所有极端情况。

由于 textFieldDidEndEditing(讽刺)类似于 android 的“可用性”,非常“高效”。

【讨论】:

【参考方案6】:

在我的例子中,textFieldDidEndEditing:(UITextField *)textField 没有被调用,因为它实现了textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason。由于某种原因,在 ios 13.4 上它没有被调用。

我修复了它,只是删除了reason ...

为什么reason 回调停止工作的问题仍然悬而未决,但短的工作正常。

【讨论】:

因为如果你使用有道理的方法,那么它不会让正常的 DidEndEditing 被调用。

以上是关于为啥 textFieldDidEndEditing: 没有被调用?的主要内容,如果未能解决你的问题,请参考以下文章

textFieldDidEndEditing 触发“为时已晚”

textFieldDidEndEditing 替代

textFieldDidEndEditing 未在 swift 中调用

在文本字段中插入一个字符后启用完成按钮: textFieldDidEndEditing: 或 textFieldShouldBeginEditing: 或?

当调用 textFieldDidEndEditing 时,应用程序冻结

如何将文本字段更改通知合并到 textFieldDidEndEditing