1
votes

I'm back again lol. My content view looks like:

struct ContentView: View {
    @ObservedObject var VModel = ViewModel()
    @State private var resultsNeedToBeUpdated: Bool = false
    var body: some View {
        VStack {
            if self.resultsNeedToBeUpdated == true {
                SearchResults(VModel: VModel, resultsNeedToBeUpdated: $resultsNeedToBeUpdated)
            }
        }
    }
}

The SearchBar view looks like:

struct SearchResults: View {
    var VModel: ViewModel
    @Binding var resultsNeedToBeUpdated: Bool
    var body: some View {
        List {
            ForEach(VModel.searchResults, id: \.self) { result in 
                Text(result)
            }
        }
    }
}

Finally, the ViewModel class looks like:

class ViewModel: ObservableObject {
    @Published var searchResults: [String] = []
    func findResults(address: String) {
        let Geocoder = Geocoder(accessToken: 'my access token')
        searchResults = []
        Geocoder.geocode(ForwardGeocodeOptions(query: address)) { (placemarks, attribution, error) in
            guard let placemarks = placemarks
            else {
                return
            }
            for placemark in placemarks {
                self.searchResults.append(placemark.formattedName)
                print("Formatted name is: \(placemark.formattedName)") //this works
            }
        }
      //I'm doing my printing on this line and it's just printing an empty array ;(
}

The variable 'resultsNeedToBeUpdated' is a boolean Binding that is updated when the user types some text into a search bar view, and it essentially just tells you that the SearchResults view should be displayed if it's true and it shouldn't be displayed if it's false. What I'm trying to do is update the SearchResults view depending on what the user has typed in.

The error is definitely something with the display of the SearchResults view (I think it's only displaying the initial view, before the array is updated). I tried using a binding because I thought it would cause the ContentView to reload and it would update the SearchResultsView but that didn't work.

1

1 Answers

2
votes

Make view model observed, in this case it will update view every time the used @Published var searchResults property is changed

struct SearchResults: View {
    @ObservedObject var VModel: ViewModel
//    @Binding var resultsNeedToBeUpdated: Bool // << not needed here

additionally to above published properties should be updated on main queue, as

DispatchQueue.main.async {
    self.searchResults = placemarks.compactMap{ $0.formattedName }

//    for placemark in placemarks {
//        print("Formatted name is: \(placemark.formattedName)") //this works
//    }
}