如何在 SwiftUI 中的异步操作期间显示 ProgressView
How to display ProgressView during an async operation in SwiftUI
您好!
我想在我的操作过程中显示进度。我是 swift 和 swiftui 的新手。请帮忙...
这是带有一种异步方法的模型:
class CountriesViewModel : ObservableObject {
@Published var countries: [String] = [String]()
@Published var isFetching: Bool = false
@MainActor
func fetch() async {
countries.removeAll()
isFetching = true
countries.append("Country 1")
Thread.sleep(forTimeInterval: 1)
countries.append("Country 2")
Thread.sleep(forTimeInterval: 1)
countries.append("Country 3")
Thread.sleep(forTimeInterval: 1)
isFetching = false
}
}
和 ContentView:
struct ContentView: View {
@StateObject var countriesVM = CountriesViewModel()
var body: some View {
ZStack {
if (countriesVM.isFetching) {
ProgressView("Fetching...")
}
else {
List {
ForEach(countriesVM.countries, id: \.self) { country in
Text(country)
}
}
.task {
await countriesVM.fetch()
}
.refreshable {
Task {
await countriesVM.fetch()
}
}
}
}
}
}
不显示进度。我做错了什么?
您可以试试这个简单的方法:
struct ContentView: View {
@StateObject var countriesVM = CountriesViewModel()
var body: some View {
ZStack {
if (countriesVM.isFetching) {
ProgressView("Fetching...")
}
else {
List {
ForEach(countriesVM.countries, id: \.self) { country in
Text(country)
}
}
.refreshable {
Task {
await countriesVM.fetch()
}
}
}
}
.task { // <-- here
await countriesVM.fetch()
}
}
class CountriesViewModel : ObservableObject {
@Published var countries: [String] = [String]()
@Published var isFetching: Bool = true // <-- here
@MainActor
func fetch() async {
countries.removeAll()
isFetching = true
countries.append("Country 1")
Thread.sleep(forTimeInterval: 1)
countries.append("Country 2")
Thread.sleep(forTimeInterval: 1)
countries.append("Country 3")
Thread.sleep(forTimeInterval: 1)
isFetching = false
}
}
}
EDIT-1:包括一个刷新数据的按钮。
struct ContentView: View {
@StateObject var countriesVM = CountriesViewModel()
var body: some View {
ZStack {
if countriesVM.isFetching {
ProgressView("Fetching...")
}
else {
VStack {
Button("refresh", action: {
Task { await countriesVM.fetch() }
}).buttonStyle(.bordered)
List {
ForEach(countriesVM.countries, id: \.self) { country in
Text(country)
}
}
.refreshable {
await countriesVM.fetch()
}
}
}
}
.task {
await countriesVM.fetch()
}
}
class CountriesViewModel : ObservableObject {
@Published var countries: [String] = [String]()
@Published var isFetching: Bool = false
@MainActor
func fetch() async {
countries.removeAll()
isFetching = true
// representative background async process
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 2) {
// eventualy, updates on the main thread for the UI to use
DispatchQueue.main.async {
self.countries.append("Country 1")
self.countries.append("Country 2")
self.countries.append("Country 3")
self.isFetching = false
}
}
}
}
}
您好! 我想在我的操作过程中显示进度。我是 swift 和 swiftui 的新手。请帮忙... 这是带有一种异步方法的模型:
class CountriesViewModel : ObservableObject {
@Published var countries: [String] = [String]()
@Published var isFetching: Bool = false
@MainActor
func fetch() async {
countries.removeAll()
isFetching = true
countries.append("Country 1")
Thread.sleep(forTimeInterval: 1)
countries.append("Country 2")
Thread.sleep(forTimeInterval: 1)
countries.append("Country 3")
Thread.sleep(forTimeInterval: 1)
isFetching = false
}
}
和 ContentView:
struct ContentView: View {
@StateObject var countriesVM = CountriesViewModel()
var body: some View {
ZStack {
if (countriesVM.isFetching) {
ProgressView("Fetching...")
}
else {
List {
ForEach(countriesVM.countries, id: \.self) { country in
Text(country)
}
}
.task {
await countriesVM.fetch()
}
.refreshable {
Task {
await countriesVM.fetch()
}
}
}
}
}
}
不显示进度。我做错了什么?
您可以试试这个简单的方法:
struct ContentView: View {
@StateObject var countriesVM = CountriesViewModel()
var body: some View {
ZStack {
if (countriesVM.isFetching) {
ProgressView("Fetching...")
}
else {
List {
ForEach(countriesVM.countries, id: \.self) { country in
Text(country)
}
}
.refreshable {
Task {
await countriesVM.fetch()
}
}
}
}
.task { // <-- here
await countriesVM.fetch()
}
}
class CountriesViewModel : ObservableObject {
@Published var countries: [String] = [String]()
@Published var isFetching: Bool = true // <-- here
@MainActor
func fetch() async {
countries.removeAll()
isFetching = true
countries.append("Country 1")
Thread.sleep(forTimeInterval: 1)
countries.append("Country 2")
Thread.sleep(forTimeInterval: 1)
countries.append("Country 3")
Thread.sleep(forTimeInterval: 1)
isFetching = false
}
}
}
EDIT-1:包括一个刷新数据的按钮。
struct ContentView: View {
@StateObject var countriesVM = CountriesViewModel()
var body: some View {
ZStack {
if countriesVM.isFetching {
ProgressView("Fetching...")
}
else {
VStack {
Button("refresh", action: {
Task { await countriesVM.fetch() }
}).buttonStyle(.bordered)
List {
ForEach(countriesVM.countries, id: \.self) { country in
Text(country)
}
}
.refreshable {
await countriesVM.fetch()
}
}
}
}
.task {
await countriesVM.fetch()
}
}
class CountriesViewModel : ObservableObject {
@Published var countries: [String] = [String]()
@Published var isFetching: Bool = false
@MainActor
func fetch() async {
countries.removeAll()
isFetching = true
// representative background async process
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 2) {
// eventualy, updates on the main thread for the UI to use
DispatchQueue.main.async {
self.countries.append("Country 1")
self.countries.append("Country 2")
self.countries.append("Country 3")
self.isFetching = false
}
}
}
}
}