在SwiftUI中动态更新列表?

时间:2020-05-25 12:44:04

标签: xcode view binding swiftui observableobject

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

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 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,但这没有用。

1 个答案:

答案 0 :(得分:2)

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

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

除上述发布的属性外,还应在主队列上更新,例如

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

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