The progressview() does not activate first time through my custom search view but works great on every subsequent search operation.
I have a firebase database backend and am using async/await functionality.
I’m trying to make the progressview appear when the user clicks the "Search" button.
Here is a minimal reproducible code example…
import SwiftUI
import Firebase
import FirebaseFirestore
import FirebaseAuth
import Combine
struct PlayGroupSearchCoursesView: View {
@StateObject var playGroupViewModel = PlayGroupViewModel()
@StateObject var courseListViewModel = CourseListViewModel()
@State var searchText = ""
@State var isFetching = false
@State var activeSearchAttribute: Int = 0
var body: some View {
NavigationView {
ScrollView {
HStack {
HStack {
TextField("Search", text: $searchText)
.textCase(.lowercase)
.autocapitalization(.none)
.padding(.leading, 24)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
.background(Color(.systemGray5))
.cornerRadius(8)
.padding(.horizontal)
// overlay (could have used zstack) the icons into the search bar itself
Button(action: {
// this shows spinner on 2nd and all searches thereafter
// it DOES NOT show the spinner in during the first search.
isFetching = true
print("fetch started")
searchText = searchText.lowercased()
Task.init {
await self.courseListViewModel.reloadSearchCourses(searchText: searchText, nameOrCity: activeSearchAttribute)
isFetching = false // as soon as the search results return, dismiss the spinner.
print("fetch complete...")
}
// this works perfectly every time
// isFetching = true
// print("stalling for 3 seconds")
// DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
// print("3 seconds are up...")
// isFetching = false
// }
}, label: {
Text("Search")
.padding(.trailing)
})
}
ZStack { //this will always show ProgressView(). won't get blocked.
Color.green.edgesIgnoringSafeArea(.all)
}
if (isFetching) {
ZStack { //this will always show ProgressView(). won't get blocked.
Color.red.edgesIgnoringSafeArea(.all)
}
ZStack {
Color(.systemBackground)
// .opacity(0.7)
.ignoresSafeArea()
ProgressView("Please wait...")
.progressViewStyle(CircularProgressViewStyle(tint: .blue))
.scaleEffect(1.5)
.padding()
}
}
//
// present a list of search results
//
ForEach(0...10, id: .self) { idx in
Text("I found this many courses: (courseListViewModel.searchCourses.count)")
}
}
.navigationTitle("Golf Course Search")
} // nav view
}
}
struct PlayGroupSearchCoursesView_Previews: PreviewProvider {
static var previews: some View {
PlayGroupSearchCoursesView()
}
}
// this foreach above (not shown) simply lists out the array of search results >
Again, this all works perfect the 2nd time the user searches for something. The first search works great and returns the results but no spinner appears for that first search.
Thanks.
Here is a screenshot of the search form and the progressView when it’s working.
2
Answers
Sometimes, your
ProgressView()
can be blocked by some random view because you did not notice.Usually, place your
ProgressView()
asoverlay
on top of the main stack might solve this accident issue.Most probably it is because your default
is true, so when you start searching and make it true there is no change and view is not refreshed and you don’t see anything at first time. Following toggling makes things work.
So, simple make it false by default
But as always, assumptions are not reliable – actually minimal reproducible example needed, take it into account for future posts.