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
相关产品推荐
相关产品推荐

