I have a view that makes an API call to pull nearby restaurant data and display it in a list. I've placed a button in the navigation bar of that view to display a sheet which will ultimately show the user filter options. For now, it uses a Picker placed in a form to allow the user to pick how they want to sort the results. I am using a variable with a @Binding property wrapper in the filter view to pass the selected value to a @State variable in the restaurant data view (selectedOption). It all works great until the view is reloaded. Either by going to a different view or relaunching the app. It appears the selectedOption variable in my API call in the onAppear function of the restaurant data view is being reset to what I've set the default value to when I defined the @State variable. I am wondering if there is a way to persist the value of what was chosen in the filter view through view reloads of the restaurant data view.
Restaurant data view:
import SwiftUI
import SwiftyJSON
import SDWebImageSwiftUI
struct RestaurantsView: View {
@EnvironmentObject var locationViewModel: LocationViewModel
@EnvironmentObject var venueDataViewModel: VenueDataViewModel
@State var selectedOption: String = "rating"
@State private var showingSheet = false
@State private var searchText = ""
@State private var showCancelButton: Bool = false
var body: some View {
let CPLatitude: Double = locationViewModel.lastSeenLocation?.coordinate.latitude ?? 0.00
let CPLongitude: Double = locationViewModel.lastSeenLocation?.coordinate.longitude ?? 0.00
GeometryReader { geometry in
VStack {
Text("Restaurants")
.padding()
List(venueDataViewModel.venuesListTen) { index in
NavigationLink(destination: RestaurantsDetailView(venue: index)) {
HStack {
VStack(alignment: .leading, spacing: 6) {
Text(index.name ?? "")
.font(.body)
.lineLimit(2)
Text(index.address ?? "")
.font(.subheadline)
.lineLimit(2)
}
}
}
Spacer()
if index.image != nil {
WebImage(url: URL(string: index.image ?? ""), options: .highPriority, context: nil)
.resizable()
.frame(width: 70, height: 70, alignment: .center)
.aspectRatio(contentMode: .fill)
.cornerRadius(12)
}
}
Text("Selected: \(selectedOption)")
Spacer()
}.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
showingSheet.toggle()
}, label: {
Image(systemName: "line.horizontal.3")
.imageScale(.large)
}
)
.sheet(isPresented: $showingSheet, content: {
NavigationView {
RestaurantsFilterView(selectedOption: self.$selectedOption)
}
})
}
}
.onAppear {
venueDataViewModel.retrieveVenues(latitude: CPLatitude, longitude: CPLongitude, category: "restaurants", limit: 50, sortBy: selectedOption, locale: "en_US") { (response, error) in
if let error = error {
print("\(error)")
}
}
}
}
}
}
Filter view:
import SwiftUI
struct RestaurantsFilterView: View {
@EnvironmentObject var locationViewModel: LocationViewModel
@EnvironmentObject var venueDataViewModel: VenueDataViewModel
var sortOptions = ["rating", "review_count"]
@Binding var selectedOption: String
var body: some View {
let CPLatitude: Double = locationViewModel.lastSeenLocation?.coordinate.latitude ?? 0.00
let CPLongitude: Double = locationViewModel.lastSeenLocation?.coordinate.longitude ?? 0.00
VStack {
Text("Filter")
Form {
Section {
Picker(selection: $selectedOption, label: Text("Sort")) {
ForEach(sortOptions, id: \.self) {
Text($0)
}
}.onChange(of: selectedOption) { Equatable in
venueDataViewModel.retrieveVenues(latitude: CPLatitude, longitude: CPLongitude, category: "restaurants", limit: 50, sortBy: selectedOption, locale: "en_US") { (response, error) in
if let error = error {
print("\(error)")
}
}
}
}
}
}
}
}
I am still new to Swift and SwiftUI so I appreciate the help. Thank you!