UITextField点击清除按钮后键盘收起又弹出,如何解决?
UITextField点击清除按钮后键盘收起又弹出的解决方法
问题背景
在Storyboard中设置UITextField的清除按钮为「始终可见」,通过.editingChanged事件监听文本变化,当文本为空时调用resignFirstResponder()收起键盘。但点击清除按钮清空文本后,键盘会先收起再立即弹出,用退格键清空则正常。
原因
点击清除按钮时,系统触发.editingChanged事件后,会自动重新激活UITextField(将其设为第一响应者),导致键盘再次弹出;而退格键清空文本时没有这个后续的系统激活操作。
方案一:延迟执行收起键盘操作
通过延迟调用resignFirstResponder(),避开系统后续的自动激活逻辑,修改你的处理方法即可:
@objc func searchTextFieldDidChange(textField: UITextField){ if let text = textField.text, text.isEmpty { // 延迟0.1秒执行,让系统的后续操作先完成 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { textField.resignFirstResponder() } } fireSearch() }
方案二:自定义UITextField接管清除按钮逻辑
通过自定义UITextField直接处理清除按钮的点击事件,完全规避系统的默认行为:
- 创建自定义TextField类:
class CustomSearchTextField: UITextField { override func layoutSubviews() { super.layoutSubviews() // 获取系统自带的清除按钮,替换点击事件 if let clearButton = value(forKey: "_clearButton") as? UIButton { clearButton.removeTarget(nil, action: nil, for: .allEvents) clearButton.addTarget(self, action: #selector(handleClearButtonTap), for: .touchUpInside) } } @objc private func handleClearButtonTap() { // 清空文本 text = "" // 直接收起键盘 resignFirstResponder() // 触发编辑改变事件,保证原有业务逻辑正常执行 sendActions(for: .editingChanged) } }
- 在Storyboard中把你的UITextField的类改为
CustomSearchTextField,原有的.editingChanged监听和fireSearch()逻辑无需修改。
内容的提问来源于stack exchange,提问作者Gerd Castan
相关产品推荐
相关产品推荐

