如何在 swift UI 中忽略容器的安全区域并尊重内容的安全区域

CTO*_*ton 7 keyboard gesture ios swift swiftui

我正在尝试在 swift ui 中创建一个看起来像这样的底表

https://user-images.githubusercontent.com/33900517/172068237-4dd58374-b6e6-4340-a913-7085fb64b254.mp4

我的问题是我有一个动画底部工作表,但由于它忽略了安全区域,因此当我单击文本字段时,它不会随键盘展开

我该如何解决这个问题,以便视图随键盘扩展,但底部的白色仍然超出安全区域?

即包含视图应忽略安全区域,并且其中的内容应遵守安全区域。

这是底部的代码片段,完整的示例可以在这里找到 https://gist.github.com/CTOverton/4fbfb8db2de31f3b5f5ef9ee88e8f744

   var body: some View {
    GeometryReader { geometry in
      VStack() {
        self.content
      }
      .padding(.vertical, 34)
      .padding(.horizontal, 16)
//      .frame(width: geometry.size.width, height: geometry.size.height * heightRatio, alignment: .top)
      .frame(width: geometry.size.width, height: self.maxHeight, alignment: .top)
      .background(Color(.white))
      .cornerRadius(Constants.radius)
      .frame(height: geometry.size.height, alignment: .bottom)
      .offset(y: max(self.offset + self.translation, 0))
      .animation(.interactiveSpring())
      .gesture(
          DragGesture().updating(self.$translation) { value, state, _ in
                state = value.translation.height
              }.onEnded { value in
                let snapDistance = self.maxHeight * Constants.snapRatio
                guard abs(value.translation.height) > snapDistance else {
                  return
                }
                self.isOpen = value.translation.height < 0
              }
      )
    }
    .edgesIgnoringSafeArea([.bottom, .horizontal])
    .shadow(color: Color(hue: 1.0, saturation: 0.0, brightness: 0.0, opacity: 0.08), radius: 12, y: -8)
  }
Run Code Online (Sandbox Code Playgroud)

我已经尝试了.ignoreSafeArea()和的各种配置.safeAreaInset(),但我似乎无法完全正确。

这里也有一些图片供参考

底板关闭 底板打开 底部工作表打开并选择文本字段,键盘处于活动状态

Asp*_*eri 5

实际上,我们不是忽略一切的安全区域(这会导致问题),而是只在背景中需要它,所以问题是在这种情况下如何正确构建背景。

注意:.cornerRadius 在这里也不合适,因为它会剪辑内容

演示

这是修复的主要部分。使用 Xcode 13.4 / iOS 15.5 进行测试

.background(
    RoundedRectangle(cornerRadius: Constants.radius)  // corners !!
        .fill(.white)                                 // background !!
        .edgesIgnoringSafeArea([.bottom, .horizontal]) // << only here !!
)
Run Code Online (Sandbox Code Playgroud)

完整的测试模块在这里