As of Xcode 12 测试版 (iOS 14),一个新视图称为ProgressView
is 可供开发人员使用 https://developer.apple.com/documentation/swiftui/progressview?changes=latest_major,并且可以显示确定和不确定的进度。
它的样式默认为CircularProgressViewStyle
,这正是我们正在寻找的。
var body: some View {
VStack {
ProgressView()
// and if you want to be explicit / future-proof...
// .progressViewStyle(CircularProgressViewStyle())
}
}
Xcode 11.x
相当多的观点尚未在SwiftUI
,但很容易将它们移植到系统中。
你需要包裹UIActivityIndicator
并做到UIViewRepresentable
.
(有关此内容的更多信息,请参阅精彩的 WWDC 2019 演讲 -集成 SwiftUI https://developer.apple.com/wwdc19/231)
struct ActivityIndicator: UIViewRepresentable {
@Binding var isAnimating: Bool
let style: UIActivityIndicatorView.Style
func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView {
return UIActivityIndicatorView(style: style)
}
func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) {
isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
}
}
然后您可以按如下方式使用它 - 这是加载覆盖的示例。
注意:我更喜欢使用ZStack
, 而不是overlay(:_)
,所以我确切地知道我的实施中发生了什么。
struct LoadingView<Content>: View where Content: View {
@Binding var isShowing: Bool
var content: () -> Content
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .center) {
self.content()
.disabled(self.isShowing)
.blur(radius: self.isShowing ? 3 : 0)
VStack {
Text("Loading...")
ActivityIndicator(isAnimating: .constant(true), style: .large)
}
.frame(width: geometry.size.width / 2,
height: geometry.size.height / 5)
.background(Color.secondary.colorInvert())
.foregroundColor(Color.primary)
.cornerRadius(20)
.opacity(self.isShowing ? 1 : 0)
}
}
}
}
要测试它,您可以使用以下示例代码:
struct ContentView: View {
var body: some View {
LoadingView(isShowing: .constant(true)) {
NavigationView {
List(["1", "2", "3", "4", "5"], id: \.self) { row in
Text(row)
}.navigationBarTitle(Text("A List"), displayMode: .large)
}
}
}
}
Result: