如何在SwiftUI中访问安全区域大小?

如何在SwiftUI中访问安全区域大小?,swiftui,Swiftui,我想手动将SwiftUI中视图的框架高度设置为屏幕安全区域的大小。很容易获得屏幕的边界(UIScreen.main.bounds),但我找不到访问安全区域大小的方法。您可以使用GeometryReader访问安全区域。 请参阅: struct ContentView:View{ var body:一些观点{ GeometryReader{中的几何体 VStack{ 垫片() 颜色:红色 .框架( 宽度:geometry.size.width, 高度:geometry.safeAreaInsets

我想手动将SwiftUI中视图的框架高度设置为屏幕安全区域的大小。很容易获得屏幕的边界(
UIScreen.main.bounds
),但我找不到访问安全区域大小的方法。

您可以使用
GeometryReader
访问安全区域。
请参阅:

struct ContentView:View{
var body:一些观点{
GeometryReader{中的几何体
VStack{
垫片()
颜色:红色
.框架(
宽度:geometry.size.width,
高度:geometry.safeAreaInsets.top,
对齐:。居中
)
.aspectRatio(contentMode:contentMode.fit)
}
}
.edgesIgnoringSafeArea(.bottom)
}
}

但仅供参考:安全区域不是一个大小。这是一个
边插入集

不确定为什么接受的答案使用顶部插入作为放置在底部插入下的视图-这些是不同的。 此外,如果您更正此“输入错误”,您将看到
GeometryReader上调用的
edgesIgnoringSafeArea
将相应的值归零。看起来在iOS 13上不是这样,但现在是这样,因此您需要在
GeometryReader
子系统上调用
edgesIgnoringSafeArea
,而此代码在iOS 13上仍能正常工作:

GeometryReader { geometry in
    VStack {
        Spacer()
        Color.red
            .frame(
                width: geometry.size.width,
                height: geometry.safeAreaInsets.bottom,
                alignment: .center
            )
            .aspectRatio(contentMode: ContentMode.fit)
    }
    .edgesIgnoringSafeArea(.bottom)
}

如果在父视图上使用
edgesIgnoringSafeArea
,并且希望访问设备
UISafeAreaInsets
,则可以执行以下操作:

代码

私有结构安全区域插入密钥:环境密钥{
静态var默认值:EdgeInsets{
(UIApplication.shared.windows.first(其中:{$0.isKeyWindow})?.safeAreaInsets???.zero)。insets
}
}
扩展环境值{
var安全区域插图:边缘插图{
self[安全区域insertskey.self]
}
}
专用扩展向导集{
变量插图:边缘插图{
边集合(顶部:顶部,前导:左侧,底部:底部,尾随:右侧)
}
}
用法

struct MyView:View{
@环境(\.safeAreaInsets)专用var safeAreaInsets
var body:一些观点{
文本(“Ciao”)
.衬垫(安全区域插图)
}
}

假设windows[0]将返回UIWindow是不安全的。根据Padam Thapan()在本博客中提供的信息,当键盘出现在屏幕上时,此数组中的第一个元素可能会成为UITextEffectsSwindow。我觉得更好的解决方案是在结构中封装对keyWindow的引用,并将其放入环境中。这将使我们能够方便地访问上述扩展。@Shengchalover谢谢您的反馈,我更新了我的答案。我决定不捕获对keyWindow的引用,因为我们不知道它是否会更改。此代码未编译,您应该使用:static var defaultValue:EdgeInsets{UIApplication.shared.windows.first(其中:{$0.isKeyWindow})?.safeAreaInsets.insets??EdgeInsets()}@FarouK现在应该可以使用此选项在横向视图中居中,因为主指示器,所以“y”的偏移只能在方向在横向视图中应用,不是吗?如果在父视图上使用.IgnoreSaareA,则此选项不起作用。