在 SwiftUI 中动态更新列表?

Dynamically updating a list in SwiftUI?

我又回来了哈哈。我的内容视图如下所示:

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)
            }
        }
    }
}

SearchBar 视图如下所示:

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

最后,ViewModel class 看起来像:

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 ;(
}

变量 'resultsNeedToBeUpdated' 是一个布尔值绑定,当用户在搜索栏视图中键入一些文本时它会更新,它基本上只是告诉您如果 SearchResults 视图为真则应该显示它应该如果为假,则显示。我要做的是根据用户输入的内容更新 SearchResults 视图。

错误肯定与 SearchResults 视图的显示有关(我认为它只显示初始视图,在数组更新之前)。我尝试使用绑定,因为我认为它会导致 ContentView 重新加载并且它会更新 SearchResultsView 但这不起作用。

观察视图模型,在这种情况下,每次使用的 @Published var searchResults 属性 改变时它都会更新视图

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

除上述已发布的属性外,还应在主队列中进行更新,因为

DispatchQueue.main.async {
    self.searchResults = placemarks.compactMap{ [=11=].formattedName }

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