基于键盘高度更新文本框约束:解决触发顺序导致高度为0的问题
解决键盘高度在
textFieldDidBeginEditing中无法正确获取的问题 嘿,这个坑我刚入门iOS开发时也踩过!确实,系统触发事件的顺序刚好和你预期的相反:用户点击文本框时,先调用textFieldDidBeginEditing,之后才会发出键盘将要显示的通知,所以这时候你拿到的heightOfKeyboard自然是初始的0.0。咱们换个思路就能完美解决,具体方案如下:
1. 把约束更新逻辑完全移到键盘通知回调里
别再试图在textFieldDidBeginEditing里拿键盘高度了,调整文本框约束的代码应该放到UIKeyboardWillShowNotification的回调方法中——这才是系统告诉你键盘真实高度的可靠时机。
示例代码(Swift)
首先在视图加载阶段注册键盘相关通知:
override func viewDidLoad() { super.viewDidLoad() // 注册键盘显示/隐藏的通知 NotificationCenter.default.addObserver( self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil ) NotificationCenter.default.addObserver( self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil ) }
然后实现通知的回调方法,在这里获取键盘高度并更新约束:
@objc private func keyboardWillShow(_ notification: Notification) { // 从通知的userInfo中取出键盘最终的frame guard let userInfo = notification.userInfo, let keyboardEndFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } // 转换坐标后获取键盘的真实高度(自动适配屏幕旋转) let keyboardHeight = view.convert(keyboardEndFrame, from: nil).height // 更新文本框的底部约束(假设你有一个IBOutlet连接的bottomConstraint) textFieldBottomConstraint.constant = keyboardHeight // 执行动画,让约束变化和键盘弹出的动画同步 UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } } @objc private func keyboardWillHide(_ notification: Notification) { // 键盘隐藏时恢复文本框的原始底部约束 textFieldBottomConstraint.constant = 20 // 这里替换成你原本的底部间距值 UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } }
最后别忘了在视图销毁时移除通知,避免内存泄漏:
deinit { NotificationCenter.default.removeObserver(self) }
2. 额外注意事项
- 不要写死键盘高度(比如直接用250这种固定值),不同设备、不同输入法的键盘高度差异很大,通知返回的frame才是最准确的
- 必须处理键盘隐藏的逻辑,否则文本框会一直停留在靠近键盘的位置,影响后续交互
- 如果你的APP支持横屏,
keyboardFrameEndUserInfoKey返回的frame已经适配了当前屏幕方向,直接转换后取高度即可
内容的提问来源于stack exchange,提问作者Giacomo Dughiero
相关产品推荐
相关产品推荐

