UITextField切换isSecureEntry时键盘收起 密码显隐切换失效
问题原因
切换UITextField的isSecureTextEntry属性时,iOS系统会默认让输入框主动放弃第一响应者身份,直接触发键盘收起,同时会中断显隐状态的切换逻辑,最终出现你遇到的异常。你实现的点击空白区域收键盘逻辑和这个问题无关,不需要修改。
修复代码
只需要修改扩展中togglePasswordView方法的实现,切换显隐状态前先记录输入框当前的第一响应状态,切换完成后重新激活输入框即可,完整可直接使用的扩展代码如下:
extension UITextField { fileprivate func setPasswordToggleImage(_ button: UIButton) { if isSecureTextEntry { button.setImage(UIImage(named: "eye_circle"), for: .normal) } else { button.setImage(UIImage(named: "eye-off"), for: .normal) } } func enablePasswordToggle(){ let button = UIButton(type: .custom) setPasswordToggleImage(button) button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -16, bottom: 0, right: 0) button.frame = CGRect(x: self.frame.size.width - 25, y: 5, width: 25, height: 25) button.tintColor = UIColor(white: 1, alpha: 0.5) button.addTarget(self, action: #selector(self.togglePasswordView), for: .touchUpInside) self.rightView = button self.rightViewMode = .always } @objc func togglePasswordView(_ sender: Any) { // 记录切换前的第一响应状态 let wasFirstResponder = isFirstResponder // 切换密码显隐状态 isSecureTextEntry.toggle() setPasswordToggleImage(sender as! UIButton) // 恢复第一响应状态,避免键盘自动收起 if wasFirstResponder { becomeFirstResponder() } } }
你原来的调用方式passwordTextField.enablePasswordToggle()不需要做任何改动,替换扩展代码后即可正常使用。
可选优化点
- 目前切换按钮使用固定frame布局,当输入框尺寸因屏幕适配、横竖屏切换发生变化时,按钮位置会错位,可以改用自动布局约束按钮的位置和尺寸,或者在输入框的
layoutSubviews回调中更新按钮frame适配布局变化 - 部分iOS系统版本下切换
isSecureTextEntry会自动清空输入框已输入的内容,可以在切换前临时保存text属性值,切换完成后重新赋值避免内容丢失
内容的提问来源于stack exchange,提问作者iLayoutConstraints
相关产品推荐
相关产品推荐

