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

SwiftUI中.ignoresSafeArea偶发未包含键盘预测文本栏问题求助

SwiftUI视图被键盘截断的异常问题

问题代码

struct MyRootSwiftUIView: View {
 var body: some View {
   VStack{}
     .ignoresSafeArea(.container, edges: [.bottom])
 }
}

场景与异常表现

  • 该SwiftUI视图由UIViewControllerA承载,预期唤起键盘时视图紧贴键盘上方显示。
  • 异常触发路径:
    1. 打开App内另一个唤起键盘的UIViewControllerB(该控制器不显示预测文本栏)
    2. 关闭UIViewControllerB,键盘随之收起
    3. 打开UIViewControllerA,唤起键盘并展示SwiftUI视图
  • 此时MyRootSwiftUIView偶尔会被键盘截断约预测文本栏的高度;直接打开UIViewControllerA则无异常,推测是系统残留了UIViewControllerB的安全区域设置。
  • 环境:iPhone,iOS 16.3.1(注:原描述的26.3.1应为笔误)
  • 问题难以稳定复现,重启App后恢复正常。

问题定性

这属于iOS 16部分版本中,SwiftUI与UIKit跨视图控制器交互时的安全区域同步已知bug,Apple在后续iOS 17版本中针对这类安全区域状态残留问题做了修复。

可行解决方案

1. 强制UIViewControllerA刷新安全区域

在UIViewControllerA的viewWillAppear中手动触发布局更新,强制同步安全区域状态:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    setNeedsUpdateOfHomeIndicatorAutoHidden()
    view.setNeedsLayout()
    view.layoutIfNeeded()
}

2. 动态监听键盘高度调整布局

放弃依赖系统安全区域自动计算,直接通过键盘通知获取实际高度,调整视图底部padding:

struct MyRootSwiftUIView: View {
    @State private var keyboardHeight: CGFloat = 0
    
    var body: some View {
        VStack{}
            .padding(.bottom, keyboardHeight)
            .ignoresSafeArea(.container, edges: .bottom)
            .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in
                guard let frame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
                keyboardHeight = frame.height
            }
            .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
                keyboardHeight = 0
            }
    }
}

3. 重置UIViewControllerB的安全区域状态

在UIViewControllerB关闭时,重置其关联的窗口安全区域状态:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    view.window?.safeAreaInsets = .zero
    view.window?.setNeedsLayout()
    view.window?.layoutIfNeeded()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 10:04:59