如何在视图渲染前获取键盘高度 布局常驻键盘页面的UI元素
解决方案
优先推荐使用系统原生适配方案,无需手动计算键盘高度,其次提供提前获取高度的实现方式:
方案1:iOS 15+ 原生键盘布局引导(最优解)
iOS 15 以后系统提供了keyboardLayoutGuide,会自动跟随键盘位置调整约束,无需监听通知、无需提前获取高度,自动适配 safe area 与键盘的间隔:
if #available(iOS 15.0, *) { // 仅需约束UITextView底部到键盘布局引导的顶部即可 redTextView.bottomAnchor.constraint(equalTo: view.keyboardLayoutGuide.topAnchor, constant: -16).isActive = true // 顶部正常约束到安全区顶部 redTextView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16).isActive = true // 左右约束按需求配置即可 }
该方案会自动处理键盘的显隐、高度变化,哪怕页面初始化时键盘就保持显示,也不会出现布局跳变。
方案2:启动预加载缓存键盘高度(兼容全系统版本)
可以在App启动阶段提前触发键盘加载,将高度缓存到全局变量,后续任意页面都可以直接读取使用:
- 首先在全局定义存储键盘高度的变量,在
SceneDelegate或AppDelegate的启动回调中添加预加载逻辑:
// 全局缓存的键盘高度,可根据横竖屏场景区分存储 var globalKeyboardHeight: CGFloat = 336 // 可设置默认值兜底 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let window = window else { return } // 添加临时TextField触发键盘弹出 let tempTextField = UITextField(frame: .zero) window.addSubview(tempTextField) tempTextField.becomeFirstResponder() // 监听一次键盘通知获取高度 NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { note in guard let endFrame = note.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } globalKeyboardHeight = endFrame.height // 回收临时TextField tempTextField.resignFirstResponder() tempTextField.removeFromSuperview() } }
- 在目标ViewController的
viewDidLoad阶段直接读取globalKeyboardHeight配置布局即可。
方案3:提前唤起键盘同步动画适配
如果不想预加载全局缓存,可以在页面初始化阶段就唤起输入框作为第一响应者,将布局更新动画和键盘弹出动画同步,用户不会感知到布局跳变:
class TargetViewController: UIViewController { private var textViewBottomConstraint: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() // 先添加初始约束,底部临时约束到安全区底部 textViewBottomConstraint = redTextView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -16) textViewBottomConstraint.isActive = true redTextView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16).isActive = true // 提前唤起键盘 redTextView.becomeFirstResponder() // 监听键盘通知 NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) } @objc private func handleKeyboardShow(_ note: Notification) { guard let userInfo = note.userInfo, let endFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect, let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double, let curve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else { return } // 更新底部约束 textViewBottomConstraint.constant = -(endFrame.height + 16) // 和键盘动画同步更新布局,无视觉跳变 UIView.animate(withDuration: duration, delay: 0, options: .init(rawValue: curve)) { self.view.layoutIfNeeded() } } }
用户问题对应的页面截图:
内容的提问来源于stack exchange,提问作者JFortYork
相关产品推荐
相关产品推荐

