我想在SwiftUI中手动将视图的框架高度设置为屏幕安全区域的大小。获取屏幕边界(UIScreen.main.bounds)很容易,但是我找不到找到安全区域大小的方法。
Mir*_*rko 49
UIApplication.shared.windows 已弃用,您现在可以使用connectedScenes:
import SwiftUI
extension UIApplication {
var keyWindow: UIWindow? {
connectedScenes
.compactMap {
$0 as? UIWindowScene
}
.flatMap {
$0.windows
}
.first {
$0.isKeyWindow
}
}
}
private struct SafeAreaInsetsKey: EnvironmentKey {
static var defaultValue: EdgeInsets {
UIApplication.shared.keyWindow?.safeAreaInsets.swiftUiInsets ?? EdgeInsets()
}
}
extension EnvironmentValues {
var safeAreaInsets: EdgeInsets {
self[SafeAreaInsetsKey.self]
}
}
private extension UIEdgeInsets {
var swiftUiInsets: EdgeInsets {
EdgeInsets(top: top, leading: left, bottom: bottom, trailing: right)
}
}
Run Code Online (Sandbox Code Playgroud)
然后在视图中使用环境属性来获取安全区域插图:
@Environment(\.safeAreaInsets) private var safeAreaInsets
Run Code Online (Sandbox Code Playgroud)
Phi*_*hov 13
不知道为什么接受的答案使用顶部插图放置在底部视图下方 - 这些是不一样的。此外,如果您更正此“拼写错误”,您将看到edgesIgnoringSafeArea调用GeometryReader的相应值为零。看起来 iOS 13 上的情况并非如此,但现在是这样,因此您需要调用edgesIgnoringSafeArea子GeometryReader进程,并且此代码在 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)
}
Run Code Online (Sandbox Code Playgroud)
Lor*_*ngo 11
如果您edgesIgnoringSafeArea在 parentView 上使用并且想要访问该设备,UISafeAreaInsets您可以执行以下操作:
代码
private struct SafeAreaInsetsKey: EnvironmentKey {
static var defaultValue: EdgeInsets {
(UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.safeAreaInsets ?? .zero).insets
}
}
extension EnvironmentValues {
var safeAreaInsets: EdgeInsets {
self[SafeAreaInsetsKey.self]
}
}
private extension UIEdgeInsets {
var insets: EdgeInsets {
EdgeInsets(top: top, leading: left, bottom: bottom, trailing: right)
}
}
Run Code Online (Sandbox Code Playgroud)
用法
struct MyView: View {
@Environment(\.safeAreaInsets) private var safeAreaInsets
var body: some View {
Text("Ciao")
.padding(safeAreaInsets)
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以创建自定义EnvironmentValue并从“初始”传递安全区域插图View。这对我来说非常有效!
EnvironmentValueprivate struct SafeAreaInsetsEnvironmentKey: EnvironmentKey {
static let defaultValue: (top: CGFloat, bottom: CGFloat) = (0, 0)
}
extension EnvironmentValues {
var safeAreaInsets: (top: CGFloat, bottom: CGFloat) {
get { self[SafeAreaInsetsEnvironmentKey.self] }
set { self[SafeAreaInsetsEnvironmentKey.self] = newValue }
}
}
Run Code Online (Sandbox Code Playgroud)
View我们的想法是在任何潜在的父母使用之前执行此操作.edgesIgnoringSafeArea,这是它发挥作用所必需的。例如:
@main
struct YourApp: App {
@State private var safeAreaInsets: (top: CGFloat, bottom: CGFloat) = (0, 0)
var body: some Scene {
WindowGroup {
ZStack {
GeometryReader { proxy in
Color.clear.onAppear {
safeAreaInsets = (proxy.safeAreaInsets.top, proxy.safeAreaInsets.bottom)
}
}
ContentView()
.environment(\.safeAreaInsets, safeAreaInsets)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
struct SomeChildView: View {
@Environment(\.safeAreaInsets) var safeAreaInsets
...
}
Run Code Online (Sandbox Code Playgroud)
您可以使用GeometryReader访问安全区域。
请参阅:https : //developer.apple.com/documentation/swiftui/geometryreader。
struct ContentView : View {
var body: some View {
GeometryReader { geometry in
VStack {
Spacer()
Color.red
.frame(
width: geometry.size.width,
height: geometry.safeAreaInsets.top,
alignment: .center
)
.aspectRatio(contentMode: ContentMode.fit)
}
}
.edgesIgnoringSafeArea(.bottom)
}
}
Run Code Online (Sandbox Code Playgroud)
但仅供参考:她的安全区域不是大小。这是一个EdgeInsets。
| 归档时间: |
|
| 查看次数: |
711 次 |
| 最近记录: |