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

iOS适配问题:新机型键盘弹出时底部约束偏移过大求助

解决方案

问题根源在于直接使用键盘全局坐标系下的高度值,新款iPhone(如iPhone 14 Pro)的屏幕存在安全区域(底部灵动岛相关布局区域),直接取键盘高度会包含不属于视图布局范围内的部分,最终导致视图位置偏高。以下是无需静态值的适配方案:

1. 修正键盘高度计算逻辑

将键盘的全局frame转换到当前视图的坐标系中,计算出键盘在当前视图内的可见高度,以此设置约束常量:

@objc func keyboardWillShow(notification: NSNotification) {
    guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue,
          let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval,
          let curveRawValue = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else {
        return
    }
    
    // 将键盘的全局frame转换到当前视图的坐标系
    let keyboardScreenRect = keyboardFrame.cgRectValue
    let keyboardFrameInView = view.convert(keyboardScreenRect, from: nil)
    
    // 计算键盘在当前视图内的可见高度(视图底部到键盘顶部的距离)
    let keyboardVisibleHeight = view.bounds.height - keyboardFrameInView.origin.y
    changeStateContainerBottomConstraint.constant = keyboardVisibleHeight
    
    // 同步键盘弹出的动画效果
    UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: curveRawValue)) {
        self.view.layoutIfNeeded()
    }
}

2. 补充键盘隐藏的处理

同步处理键盘隐藏时的约束复位,保持交互一致性:

// 添加隐藏通知监听
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)

// 键盘隐藏处理方法
@objc func keyboardWillHide(notification: NSNotification) {
    guard let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval,
          let curveRawValue = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else {
        return
    }
    
    changeStateContainerBottomConstraint.constant = 0
    
    UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: curveRawValue)) {
        self.view.layoutIfNeeded()
    }
}

3. 内存泄漏防护

在视图控制器销毁时移除通知观察者,避免内存泄漏:

deinit {
    NotificationCenter.default.removeObserver(self)
}

原理说明

通过convert(_:from:)方法将键盘的全局坐标转换为当前视图的本地坐标,能准确获取键盘相对于当前布局视图的位置,计算出的keyboardVisibleHeight是视图底部到键盘顶部的真实距离,完全适配不同机型的安全区域差异,无需硬编码静态值。

内容的提问来源于stack exchange,提问作者Zachary Bell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 21:45:34