繁体   English   中英

如何在 SwiftUI 中使用 edgesIgnoringSafeArea,但让子视图尊重安全区域?

[英]How can I use edgesIgnoringSafeArea in SwiftUI, but make a child view respect the safe area?

我正在构建一个带有列表视图的 UI 是 SwiftUI,我想在列表视图的一部分上放置一个面板,上面有一个按钮。

在底部有安全区域(没有物理主页按钮)的设备上,我希望面板位于屏幕底部的 go。 但我想确保面板上的按钮不会延伸到安全区域。

在我的示例代码中, HStack是包含按钮的面板。 我尝试向其中添加.edgesIgnoringSafeArea(.bottom) ,但这不允许它延伸到底部。 这让我有点困惑,因为同一个ZStack中的列表延伸到底部安全区域。

当我将.edgesIgnoringSafeArea(.bottom)添加到ZStack时,允许HStack (蓝色面板)延伸到屏幕底部的安全区域。 这就是我想要的,但是一旦我这样做了,我怎么能告诉作为HStack子项的Button不要忽略安全区域?

我知道如何在 UIKit 中执行此操作,但我真的希望能够在 SwiftUI 中构建此 UI。我可以手动添加一些填充或 Spacers 以在Button下添加额外的填充以说明安全区域,但随后带有主页按钮但没有底部安全区域的设备会有额外的间距。 我想找出一个优雅的解决方案,我可以依靠系统来定义其安全区域,而不是手动定义任何数字间距或为不同设备创建条件情况。

struct ContentView: View {
    var body: some View {

        ZStack(alignment: .bottom) {

                    List {
                        Text("Item 1")
                        Text("Item 2")
                        Text("Item 3")
                    }

                    HStack {
                        Spacer()
                        Button(action: {
                            // do something
                        }){
                            Text("Button")
                                .font(.title)
                                .padding()
                                .background(Color.green)
                                .foregroundColor(.white)
                                .cornerRadius(15)
                        }.padding()
                        Spacer()
                    }.background(Color.blue).edgesIgnoringSafeArea(.bottom)
                }
    }
}

我想要的失败尝试的屏幕截图

您在背景修改器中绘制的任何视图都将使用它正在修改的视图的框架。 所以你需要告诉那个视图忽略安全区域。

.background(Color.blue.edgesIgnoringSafeArea(.bottom))

您可以使用 GeometryReader 访问安全区域的高度。 然后您可以使用安全区域的高度作为按钮的底部填充或偏移。
https://developer.apple.com/documentation/swiftui/geometryproxy

struct ContentView: View {
    var body: some View {

        GeometryReader { proxy in
            ZStack(alignment: .bottom) {

                List {
                    Text("Item 1")
                    Text("Item 2")
                    Text("Item 3")
                }

                HStack {
                    Spacer()
                    Button(action: {
                        // do something
                    }){
                        Text("Button")
                            .font(.title)
                            .padding()
                            .background(Color.green)
                            .foregroundColor(.white)
                            .cornerRadius(15)
                    }
                    .padding(.bottom, proxy.safeAreaInsets.top)
                    Spacer()
                }.background(Color.blue)
            }.edgesIgnoringSafeArea(.bottom)
        }
    }
}

添加到@Joe Susnick 的回答中,完整的代码是:

VStack {

}.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(red: 0.357, green: 0.784, blue: 0.016, opacity: 0.5).ignoresSafeArea()
)

VStack 内部的任何内容都尊重安全区域,而背景会填满整个屏幕。

edgeIgnoringSafeArea(_:) 已弃用

使用以下内容:


.background(Color.blue.ignoresSafeArea(edges: .bottom))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM