如何解决导航视图场景下UIKeyboardLayoutGuide失效的问题?
iOS 15 UIKeyboardLayoutGuide 导航栈场景失效问题解决方案
该问题属于UIKit已知实现缺陷,并非配置遗漏导致:iOS 15新增的UIKeyboardLayoutGuide特性在和UINavigationController搭配使用时,当绑定了键盘布局指南约束的控制器被压入导航栈下层、进入不可见状态,系统会主动将该控制器的keyboardLayoutGuide的frame重置为CGRect.zero,且控制器回到前台时不会主动触发重新计算,只有当键盘再次触发弹出/收起动作时,布局指南的frame才会恢复正确值,最终导致关联约束失效。
复现代码
你提供的复现代码逻辑无问题:
let kbView = UIView() kbView.backgroundColor = .green kbView.translatesAutoresizingMaskIntoConstraints = false self.view.addSubview(kbView) kbView.widthAnchor.constraint(equalToConstant: 200).isActive = true kbView.heightAnchor.constraint(equalToConstant: 100).isActive = true kbView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true kbView.bottomAnchor.constraint(equalTo: self.view.keyboardLayoutGuide.topAnchor).isActive = true
兼容解决方案
可根据业务场景选择以下任意一种修复方案:
- 方案一:视图显示时主动触发布局更新,适配成本最低,适合仅需要支持iOS 15+的场景
在对应控制器的viewWillAppear生命周期方法中添加如下代码,主动触发键盘布局指南重新计算frame:override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) view.keyboardLayoutGuide.invalidateIntrinsicContentSize() view.setNeedsLayout() view.layoutIfNeeded() } - 方案二:添加兜底约束避免布局错乱,适合对布局稳定性要求高的业务
给键盘关联的约束设置非必填优先级,同时新增一个绑定到安全区底部的兜底约束,优先级低于键盘约束,当键盘布局指南失效时兜底约束生效,避免视图位置异常:// 键盘关联约束,优先级设为默认高 let kbBottomConstraint = kbView.bottomAnchor.constraint(equalTo: view.keyboardLayoutGuide.topAnchor) kbBottomConstraint.priority = .defaultHigh kbBottomConstraint.isActive = true // 兜底约束,键盘布局失效时生效,可根据业务调整间距 let fallbackBottomConstraint = kbView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -16) fallbackBottomConstraint.priority = .defaultLow fallbackBottomConstraint.isActive = true - 方案三:自定义键盘布局指南,就是你目前使用的方案,兼容性最好,可同时覆盖iOS 15以下的系统版本,不受系统本身bug影响,适合对稳定性要求高的业务场景。
内容的提问来源于stack exchange,提问作者Fab1n
相关产品推荐
相关产品推荐

