【发布时间】:2021-09-30 08:48:10
【问题描述】:
我试图在我的 SwiftUI 应用程序中拥有一个系统范围的进度条,所以我定义了这个视图(注意:我的目标是 iOS 13+):
import SwiftUI
struct LoadingView<Content>: View where Content: View {
@Binding var isShowing: Bool
var content: () -> Content
var body: some View {
GeometryReader { _ in
ZStack {
self.content()
if self.isShowing {
VStack {
ActivityIndicator()
Text("Loading...")
}
}
}
}
}
}
struct ActivityIndicator: UIViewRepresentable {
typealias UIView = UIActivityIndicatorView
fileprivate var configuration = { (_: UIView) in }
func makeUIView(context: UIViewRepresentableContext<Self>) -> UIView { UIView() }
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<Self>) {
uiView.startAnimating()
configuration(uiView)
}
}
并且像这样在 ContenView.swift 中使用
import SwiftUI
struct ContentView: View {
@EnvironmentObject var myViewModel: MyViewModel
var body: some View {
let isLoading = Binding<Bool>(
get: { self.myViewModel.isLoading },
set: { _ in }
)
LoadingView(isShowing: isLoading) {
NavigationView {
Home()
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
}
其中 MyViewModel 是一个非常标准的 ViewModel,带有一个用于 isLoading 的 @Published var,Home() 是应用程序的主要入口点。
每当在 MyViewModel 中触发 isLoading 的某些操作完成时,进度条就会正确显示(和隐藏)。
但是,如果我通过 NavigationView 中的一个视图或使用 ContentView 本身来呈现.sheet,无论它隐藏进度条是什么。
即使我使用内置 14+ ProgressView 问题仍然存在。
.Zindex() 也无济于事。
无论.sheet、.alert 或 SwiftUI 上可用的任何覆盖视图,是否有任何方法可以让该视图在显示时始终位于顶部?
提前致谢!
【问题讨论】:
-
无论如何,您的观察应该是预期的行为,因为工作表是 modal 视图。模态应该始终显示在“计算机”需要“人类”输入的任何其他视图之上。见wiki
-
@CouchDeveloper 我明白你的意思。但是,如果我用
LoadingView视图将我的视图主体包含在.sheet中,进度条实际上会出现在模式的顶部。似乎在打开工作表时,Apple 选择以一种非常孤立的方式将两层分开。 -
当然,当您在模态视图中显示加载指示器时,它会在位于顶部的模态视图中呈现。恕我直言,从用户体验的角度来看,有一个覆盖加载指示器的模式看起来很奇怪。应用程序不应该等到结果可用之前显示警报或工作表吗?
-
Sheet 用于输入一些数据,这些数据会触发 MyViewModel(以及 isLoading 属性),并且这些触发器不一定在工作表关闭时发生。所以我在这里描述的行为。让每个 .sheet 都有自己的加载器是一种方式。从用户体验的角度来看,我支持你,在这种情况下,也许全局 ZIndex 会是实用的,但我不确定这是否是一个好习惯
-
@CouchDeveloper 能否请您根据您在 cmets 中写下的考虑来回答这个问题,以便我给予您应得的荣誉?