输入文本时TextField被键盘遮挡的技术问题求助
嘿,我来帮你搞定这个TextField被键盘遮挡的问题!看起来你已经尝试监听键盘通知了,但可能在实现细节上出了点小问题,我给你梳理下完整的解决方案,结合你现有的代码来调整:
解决TextField被键盘遮挡的问题
1. 完善键盘通知的监听与处理
你已经添加了键盘通知的观察者,但代码似乎被截断了。首先得确保注册完整的键盘通知,再实现对应的处理逻辑:
先补全viewDidLoad里的通知注册:
override func viewDidLoad() { super.viewDidLoad() // 监听键盘弹出/帧变化通知 NotificationCenter.default.addObserver(self, selector: #selector(keyboardFrameChangeNotification(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) // 监听键盘收起通知 NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHideNotification(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) // 你的其他现有代码... }
然后实现两个通知的处理方法,核心是计算view需要偏移的距离,让当前输入的TextField避开键盘:
@objc func keyboardFrameChangeNotification(_ notification: Notification) { guard let userInfo = notification.userInfo, let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect, let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else { return } // 获取当前正在输入的TextField guard let activeTextField = UIResponder.currentFirst() as? UITextField else { return } // 转换TextField的frame到当前ViewController的view坐标系 let textFieldFrame = activeTextField.convert(activeTextField.bounds, to: self.view) // 计算TextField底部到view底部的距离,对比键盘高度判断是否重叠 let textFieldBottom = textFieldFrame.origin.y + textFieldFrame.size.height let availableViewHeight = self.view.bounds.size.height - keyboardFrame.size.height let overlap = textFieldBottom - availableViewHeight // 如果有重叠,就动画偏移view;否则不处理 if overlap > 0 { UIView.animate(withDuration: duration) { self.view.transform = CGAffineTransform(translationX: 0, y: -overlap) } } } @objc func keyboardWillHideNotification(_ notification: Notification) { guard let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else { return } // 键盘收起时,恢复view的原始位置 UIView.animate(withDuration: duration) { self.view.transform = .identity } }
这里需要一个小工具方法来获取当前的第一响应者,你可以给UIResponder加个扩展:
extension UIResponder { static func currentFirst() -> UIResponder? { _currentFirstResponder = nil UIApplication.shared.sendAction(#selector(UIResponder.findFirstResponder(_:)), to: nil, from: nil, for: nil) return _currentFirstResponder } private weak static var _currentFirstResponder: UIResponder? @objc private func findFirstResponder(_ sender: Any) { UIResponder._currentFirstResponder = self } }
2. 适配TableView场景下的TextField
如果你的TextField是放在TableViewCell里的,除了上面的view偏移,还需要在编辑时滚动到对应的cell位置,避免被遮挡:
func textFieldDidBeginEditing(_ textField: UITextField) { // 找到TextField所在的cell的indexPath guard let cell = textField.superview?.superview as? UITableViewCell, let indexPath = yourTableView.indexPath(for: cell) else { return } // 滚动到该cell,确保它在可视区域 yourTableView.scrollToRow(at: indexPath, at: .middle, animated: true) }
3. 清理通知观察者避免内存泄漏
记得在ViewController销毁时移除通知观察者:
deinit { NotificationCenter.default.removeObserver(self) }
这样调整后,键盘弹出时你的view会自动偏移合适的距离,让当前输入的TextField显示在键盘上方;键盘收起时恢复原位。如果是TableView里的TextField,滚动逻辑也能确保它不被遮挡。
内容的提问来源于stack exchange,提问作者Yrb
相关产品推荐
相关产品推荐

