Как отфильтровать данные из локального файла Json с помощью панели поиска - PullRequest
0 голосов
/ 06 февраля 2020

У меня есть локальный файл json, и я уже загрузил его в свой проект. Данные в файле json выглядят так:

[
    {"id": 1, "hanzi":  "安全", "pinyin": "ān quán", "imageName": "a"},
    {"id": 2, "hanzi": "安静", "pinyin": "ān jìng", "imageName": "b"},
    {"id": 3, "hanzi": "帮助", "pinyin": "bāng zhù", "imageName": "c"},
    {"id": 4, "hanzi": "白天", "pinyin": "bán tiān", "imageName": "d"},
    {"id": 5, "hanzi": "摆", "pinyin": "bǎi","imageName": "e"}
]

Я создал VocabList.swift для отображения данных с помощью NavigationView. Теперь я хотел бы добавить панель поиска, чтобы иметь возможность поиска данных с двумя разными ключами - «ханци» и «пиньинь».

Я следовал учебному пособию онлайн и создал Searchbar.swift. Я могу вызвать его в VocabList.swift без проблем, но когда я попытался определить фильтр, он сообщил об ошибке «Невозможно указать значение неверного или неоднозначного типа».

Вот Searchbar.swift:

import SwiftUI

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
        return searchBar
    }

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

Вот VocabList.swift:

@State private var searchTerm: String = ""

var body: some View {
    NavigationView {
        VStack {
            SearchBar(text: $searchTerm)

            List(vocabData.filter{
            ($0["hanzi"] as! String).range(of: searchTerm!) != nil ||
            ($0["pinyin"] as! String).range(of: searchTerm!) != nil
            })
            { vocab in
                NavigationLink(destination: VocabDetail(vocab: vocab)) {
                    VocabRow(vocab: vocab)
                }
            }
            .navigationBarTitle(Text("Vocab"))
        }
    }
}

Я очень новичок в кодировании. Я не знаю, где пошло не так. Кто-нибудь может мне помочь? Большое спасибо!

1 Ответ

0 голосов
/ 06 февраля 2020

Измените метод searchBar - textDidChange в классе Coordinator, как указано ниже

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    // filteredData here is the result, data is the local array
    filteredData = searchText.isEmpty ? data : data.filter { (item: String) -> Bool in
        // If dataItem matches the searchText, return true to include it
        return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
    }
    // Reload UI element as per your requirement
}
...