【发布时间】:2020-11-24 19:33:00
【问题描述】:
我正在 SwiftUI 中创建一个加载指示器,它应该始终位于视图层次结构的顶层视图的中心(即在全屏应用程序中位于整个屏幕的中心)。这在 UIKit 中很容易,但是 SwiftUI 仅相对于其父视图居中视图,我无法获取父视图的父视图的位置。
遗憾的是,我的应用程序并非完全基于 SwiftUI,因此我无法轻松地在我的根视图上设置属性,然后我可以在加载视图中访问这些属性 - 无论视图层次结构如何(混合 UIKit - SwiftUI 父视图)。这就是为什么像 SwiftUI set position to centre of different view 这样的答案不适用于我的用例,因为在该示例中,您需要修改要使子视图居中的视图。
我尝试过使用View 的.offset 和.position 函数,但是,无论屏幕大小或任何部分,我都无法获得正确的输入以始终动态居中我的loadingView整个屏幕的rootView 占据。
请在下面找到该问题的最小可重现示例:
/// Loading view that should always be centered in the whole screen on the XY axis and should be the top view in the Z axis
struct CenteredLoadingView<RootView: View>: View {
private let rootView: RootView
init(rootView: RootView) {
self.rootView = rootView
}
var body: some View {
ZStack {
rootView
loadingView
}
// Ensure that `AnimatedLoadingView` is displayed above all other views, whose `zIndex` would be higher than `rootView`'s by default
.zIndex(.infinity)
}
private var loadingView: some View {
VStack {
Color.white
.frame(width: 48, height: 72)
Text("Loading")
.foregroundColor(.white)
}
.frame(width: 142, height: 142)
.background(Color.primary.opacity(0.7))
.cornerRadius(10)
}
}
应在其上方显示加载视图的视图:
struct CenterView: View {
var body: some View {
return VStack {
Color.gray
HStack {
CenteredLoadingView(rootView: list)
otherList
}
}
}
var list: some View {
List {
ForEach(1..<6) {
Text($0.description)
}
}
}
var otherList: some View {
List {
ForEach(6..<11) {
Text($0.description)
}
}
}
}
我尝试使用GeometryReader 和.frame(in: .global) 修改CenteredLoadingView 的body 以获取全局屏幕尺寸,但我所取得的是现在我的loadingView 根本不可见。
var body: some View {
GeometryReader<AnyView> { geo in
let screen = geo.frame(in: .global)
let stack = ZStack {
self.rootView
self.loadingView
.position(x: screen.midX, y: screen.midY)
// Offset doesn't work either
//.offset(x: -screen.origin.x, y: -screen.origin.y)
}
// Ensure that `AnimatedLoadingView` is displayed above all other views, whose `zIndex` would be higher than `rootView`'s by default
.zIndex(.infinity)
return AnyView(stack)
}
}
【问题讨论】:
-
应始终居中于其
rootView上方,但也应位于整个屏幕中 - 这是自相矛盾的要求。如果 rootView 是 10x10 点 topLeading - 那怎么能满足?我假设中心到根视图或全屏 - 不是两者。 -
@Asperi 不确定你从哪里得到的,这句话不在我的问题范围内。在任何情况下,加载视图都应该在整个屏幕中居中,如屏幕截图所示。
-
;) 它在您对
struct CenteredLoadingView的评论中的第一个代码快照中...是您的代码吗? -
@Asperi 我的错,忘记了文档评论并在页面上找到没有找到,但即使有该文档评论,描述和屏幕截图也应该很清楚。无论如何更新了评论,现在应该非常清楚我的要求是什么。