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

iOS:如何可靠检测所有类型软键盘的可见状态

iOS:如何可靠检测所有类型软键盘的可见状态

嗨,这个问题确实戳中了旧键盘通知方案的痛点!之前用keyboardWillShow/Hide只能管停靠键盘,遇到拆分、浮动这些特殊键盘就完全失效,keyboardWillChangeFrame又没法直接判断显隐,确实头疼。

不过你提到的UIKeyboardLayoutGuide真的是解决这个问题的金钥匙!它就是苹果为了统一所有键盘类型的布局和状态检测而推出的,完全能用来可靠判断所有软键盘的可见性。

先回顾下你说的旧方案局限:

// 旧方案:仅对停靠键盘有效
let showingObserver = NotificationCenter.default.addObserver(
  forName: UIResponder.keyboardWillShowNotification,
  object: nil,
  queue: .main
) { [weak self] _ in
  // 键盘即将显示
}

let hidingObserver = NotificationCenter.default.addObserver(
  forName: UIResponder.keyboardWillHideNotification,
  object: nil,
  queue: .main
) { [weak self] _ in
  // 键盘即将隐藏
}

这段代码对非停靠、拆分、浮动键盘完全没反应,keyboardWillChangeFrame虽然会触发,但拿到的frame变化信息太模糊,没法准确判断是显隐还是只是位置调整。

而UIKeyboardLayoutGuide的isActive属性就是专门干这个的!不管键盘是哪种类型,只要它在屏幕上可见(哪怕是浮动在中间的拆分键盘),isActive就会是true;当键盘完全收起隐藏,isActive就会变为false。

具体实现超简单,用KVO监听这个属性就行,给你写个实际可用的示例:

class YourViewController: UIViewController {
    // 持有KVO监听的引用,避免被提前释放
    private var keyboardVisibilityObserver: NSKeyValueObservation?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupKeyboardVisibilityDetection()
    }
    
    private func setupKeyboardVisibilityDetection() {
        // 监听键盘布局指南的isActive属性
        keyboardVisibilityObserver = view.keyboardLayoutGuide.observe(\.isActive, options: .new) { [weak self] _, change in
            guard let isKeyboardVisible = change.newValue else { return }
            
            if isKeyboardVisible {
                // 处理键盘显示逻辑(所有类型都适用)
                print("键盘已显示,不管是停靠/拆分/浮动/非停靠!")
            } else {
                // 处理键盘隐藏逻辑
                print("键盘已完全隐藏")
            }
        }
    }
    
    deinit {
        // 记得销毁监听,防止内存泄漏
        keyboardVisibilityObserver?.invalidate()
    }
}

这个方案的优势简直拉满:

  • 全类型覆盖:不管用户用哪种键盘模式,都能准确检测显隐
  • 逻辑简单:不用去计算frame变化、对比高度,直接通过官方提供的状态判断
  • 苹果官方推荐:基于系统布局指南,稳定性和兼容性都比自己解析通知靠谱得多

唯一要注意的是,UIKeyboardLayoutGuide是iOS 15才引入的,如果你的App需要兼容iOS 14及以下,那可能需要做个版本兼容:iOS 15+用这个方案,低版本还是用旧的通知+frame判断的组合,但如果你的部署目标已经是iOS 15+,那这绝对是最优解。

备注:内容来源于stack exchange,提问作者sm-sayedi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:34:30