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 amount of the view code...
struct PlayGroupSearchCoursesView: View {
@StateObject var playGroupViewModel = PlayGroupViewModel()
@StateObject var courseListViewModel = CourseListViewModel()
@State var masterPlayerList = [Player]()
@State var searchText = ""
@State var searchButtonState = true
@State var sval = ""
@State var isSearching = true
@State var isFetching = false
@State var activeSearchAttribute: Int = 0
@State var presentCourseAddedAlertSheet = false
@State var selectedCourseIdx: Int = 0
var body: some View {
NavigationView {
ScrollView {
HStack {
HStack {
TextField("Search", text: $searchText)
.textCase(.lowercase)
.autocapitalization(.none)
.padding(.leading, 24)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
.padding()
.background(Color(.systemGray5))
.cornerRadius(8)
.padding(.horizontal)
.onTapGesture{
isSearching = true
}
// overlay (could have used zstack) the icons into the search bar itself
if isSearching { // indicates the user has set focus to the search textfield.
Button(action: {
Task {
do {
isFetching = true // indicates the user has entered a search string and pressed the "Search" button.
print("isfetching: \(isFetching)")
searchText = searchText.lowercased()
try await self.courseListViewModel.reloadSearchCourses(searchText: searchText, nameOrCity: activeSearchAttribute)
isFetching = false // as soon as the search results return, dismiss the spinner.
} catch {
print(error)
}
}
}, label: {
Text("Search")
.padding(.trailing)
})
.disabled(!searchButtonState)
}
}
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(courseListViewModel.searchCourses.indices, id: \.self) { idx in
// 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.
CodePudding user response:
Sometimes, your ProgressView()
can be blocked by some random view because you did not notice.
Usually, place your ProgressView()
as overlay
on top of the main stack might solve this accident issue.
struct CustomView: View {
var body: some View {
ZStack { //this will always show ProgressView(). won't get blocked.
Color.red.edgesIgnoringSafeArea(.all)
}
.overlay {
ProgressView()
}
/* //this will not show ProgressView()
ZStack {
ProgressView()
Color.red.edgesIgnoringSafeArea(.all)
}*/
}
}
CodePudding user response:
Most probably it is because your default
@State var isSearching = true // << here !!
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
@State var isSearching = false // << here !!
But as always, assumptions are not reliable - actually minimal reproducible example needed, take it into account for future posts.