iOS中切换TextField时MDTimePicker弹出后数字键盘无法收起的问题
我明白你遇到的焦点冲突问题了:从带数字键盘的第一个TextField切换到唤起MDTimePicker的第二个TextField时,第一个TextField的第一响应者状态没被正确清除,导致点击Done按钮时view.endEditing(true)失效。下面是几个针对性的修复方案:
方案1:主动指定TextField放弃第一响应者(双重保险)
view.endEditing(true)有时会因为视图层级或焦点状态的细节问题失效,这时候我们可以主动让目标TextField resign第一响应者,配合全局endEditing使用:
修改你的donePressed方法:
@objc func donePressed(){ // 先强制数字键盘对应的TextField放弃焦点 self.rateInPointsTextField.resignFirstResponder() // 再调用全局endEditing确保没有遗漏的焦点 self.view.endEditing(true) }
方案2:唤起MDTimePicker前提前清除焦点
在处理第二个TextField的编辑事件时,先明确检查并清除第一个TextField的第一响应者状态,避免MDTimePicker的显示干扰焦点处理:
func textFieldDidBeginEditing(_ textField: UITextField) { if textField == self.fromTimeTextField{ // 主动检查并让数字键盘TextField放弃焦点 if self.rateInPointsTextField.isFirstResponder { self.rateInPointsTextField.resignFirstResponder() } let timePicker = MDTimePickerDialog() timePicker.delegate = self timePicker.tag = 100 timePicker.clockMode = .mode12H timePicker.show() } }
方案3:在MDTimePicker回调中再次确认键盘收起
部分第三方时间选择器显示时会修改窗口层级或焦点状态,导致原键盘的收起逻辑被干扰。你可以在MDTimePicker的选择完成代理方法中,再执行一次键盘收起操作:
// 假设MDTimePicker有选择完成的代理方法,示例如下 func timePickerDidSelectTime(_ timePicker: MDTimePickerDialog, selectedTime: Date) { // 处理你的时间选择逻辑... // 再次确保所有键盘都被收起 self.view.endEditing(true) self.rateInPointsTextField.resignFirstResponder() }
失效原因分析
你原来的代码中,点击第二个TextField时触发textFieldDidBeginEditing,虽然调用了view.endEditing(true),但MDTimePicker立即被显示,系统的焦点处理流程还没完成,导致rateInPointsTextField的第一响应者状态没有被正确移除。后续点击Done按钮时,系统可能误以为当前没有活跃的第一响应者(MDTimePicker占据了焦点),但数字键盘的TextField实际上还持有焦点,最终导致键盘无法收起。
通过主动指定rateInPointsTextField.resignFirstResponder(),我们可以直接强制它放弃焦点,确保键盘被正确收起。
内容的提问来源于stack exchange,提问作者Suhail

