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

q3qa4bjr  于 2023-01-14  发布在  iOS
关注(0)|答案(4)|浏览(211)

我正在构建一个带有列表视图的UI SwiftUI,我想在列表视图的一部分上放置一个面板,面板上有一个按钮。
在底部有安全区域的设备上(没有物理主页按钮),我希望面板位于屏幕底部,但我希望确保面板上的按钮不会延伸到安全区域。
在我的示例代码中,HStack是包含按钮的面板。我尝试向其添加.edgesIgnoringSafeArea(.bottom),但这不允许它扩展到底部。这让我有点困惑,因为在同一个ZStack中的List扩展到底部安全区域。
当我将.edgesIgnoringSafeArea(.bottom)添加到ZStack时,HStack(蓝色面板)被允许扩展到屏幕底部的安全区域,这是我想要的,但是一旦我这样做了,我如何告诉Button(它是HStack的子对象)不要忽略安全区域呢?
我知道在UIKit中该怎么做,但我真的希望能够在SwiftUI中构建这个UI。我可以手动添加一些填充或Spacers,在Button下添加额外的填充,以考虑安全区域,但在有Home键但没有底部安全区的设备上会有额外的空间。我想找出一个优雅的解决方案,我可以依靠系统来定义其安全区域,而不是手动定义任何间距数字或创建不同设备的条件情况。

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)
                }
    }
}

e4eetjau

e4eetjau1#

无论你在背景修改器中画什么视图,都会使用它正在修改的视图的框架。所以你需要告诉那个视图忽略安全区域。

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

ybzsozfc2#

你可以使用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)
        }
    }
}
uyhoqukh

uyhoqukh3#

就是deprecated
请使用以下内容:

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

cqoc49vn4#

加上@Joe Susnick的回答,完整的代码是:

VStack {

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

VStack内部的任何内容都将遵循安全区域,而背景将填充整个屏幕。

相关问题