Как отфильтровать массив объектов с помощью панели поиска в SwiftUI? - PullRequest
0 голосов
/ 18 апреля 2020

У меня есть массив объектов, и я хотел бы отфильтровать список на основе текста поиска. Это то, что у меня пока есть:

CountryListView:

func getFilteredData(data: [CountryStats], searchText: String) -> [CountryStats] {
    if searchText.isEmpty == false {
        return data.filter { $0.country == searchText }
    }
    else {
        return data
    }
}


struct CountryMasterView: View {

    @Environment(\.colorScheme) var colorScheme
    @State private var searchText: String = ""
    var countryStats: [CountryStats]

    var body: some View {
        NavigationView {
            VStack {
                SearchBar(text: $searchText)
             List {
                ForEach(countryStats.filter {
                    self.searchText.isEmpty ? true : getFilteredData(data: countryStats, searchText: searchText)
                }, id: \.self) { stat in
                if stat.country as AnyObject !== "All" as AnyObject {

                    NavigationLink(destination: CountryDetailView(countryStats: stat)) {
                        HStack {
                            URLImage(URL(string: stat.flag ?? "")!) { proxy in
                            proxy.image
                                .resizable()
                                .scaledToFit()
                                .clipped()

                            }
                                .frame(width: 50.0, height: 35.0)

                            VStack(alignment: .leading) {
                                Text(stat.country)
                                    .font(.headline)
                                Text("Total cases: \(stat.cases)")
                                    .font(.subheadline)
                            }
                        }

                  }
                }

                }


            }.navigationBarTitle("Cases By Country")
        }
        }
    }
}

Это моя модель:

struct AllCountryStats: Identifiable, Decodable {
    let id = UUID()
    var data: [CountryStats]
    let message: String
}

struct CountryStats: Identifiable, Decodable, Hashable {
    let id = UUID()
    let active, cases: Int
    let country: String
    let deaths, recovered, todayCases, todayDeaths: Int
    let flag: String?
    let updated: Double
}

И это вид поиска:

struct SearchBar: UIViewRepresentable {
    @Binding var text: String

    class Coordinator: NSObject, UISearchBarDelegate {
        @Binding var text: String

        init(text: Binding<String>) {
            _text = text
        }

        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            text = searchText
        }

    }

    func makeCoordinator() -> SearchBar.Coordinator {
        return Coordinator(text: $text)
    }

    func makeUIView(context: UIViewRepresentableContext<SearchBar>) -> UISearchBar {
        let searchBar = UISearchBar(frame: .zero)
        searchBar.delegate = context.coordinator
        searchBar.searchBarStyle = .minimal
        return searchBar
    }

    func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext<SearchBar>) {
        uiView.text = text
    }

}

Итак, я хотел бы иметь панель поиска, чтобы отфильтровать страны.

Есть что-то, чего мне не хватает, или я делаю это неправильно? Я получаю ошибку Unable to infer complex closure return type; add explicit type to disambiguate

1 Ответ

0 голосов
/ 18 апреля 2020

Есть некоторые проблемы с вашим кодом.

Сначала я заменил stat.country as AnyObject !== "All" as AnyObject на stat.country != "All".

Тогда ваш фильтр в ForEach был странным. Я сделал это проще и улучшил его, используя .contains вместо равенства строк. Это позволяет искать страну, не вводя полное имя.

Вот рабочий орган для вашего просмотра:

var body: some View {
        NavigationView {
            VStack {
                SearchBar(text: $searchText)
                List {
                    ForEach(countryStats.filter { $0.country.contains(searchText) || searchText.isEmpty }) { stat in
                        if stat.country != "All" {

                            NavigationLink(destination: CountryDetailView(countryStats: stat)) {
                                HStack {
                                    URLImage(URL(string: stat.flag ?? "")!) { proxy in
                                        proxy.image
                                            .resizable()
                                            .scaledToFit()
                                            .clipped()

                                    }
                                    .frame(width: 50.0, height: 35.0)

                                    VStack(alignment: .leading) {
                                        Text(stat.country)
                                            .font(.headline)
                                        Text("Total cases: \(stat.cases)")
                                            .font(.subheadline)
                                    }
                                }

                            }
                        }
                    }
                }.navigationBarTitle("Cases By Country")
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...