You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在视图渲染前获取键盘高度 布局常驻键盘页面的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启动阶段提前触发键盘加载,将高度缓存到全局变量,后续任意页面都可以直接读取使用:

  1. 首先在全局定义存储键盘高度的变量,在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()
    }
}
  1. 在目标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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:54:04