0

I have the following file called 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() -> 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
    }
}

Then on the ContentView.swift the following one:

import SwiftUI


struct Geolokation: Decodable,Hashable, Identifiable {
    var date: String
    var id: String
    var latitude: String
    var longitude: String
    var seq_number: String
    var accuracy: String
}

struct GeolokationDetail: View {

    var loka: Geolokation

    var body: some View {

        VStack(alignment: .leading, spacing: 10) {
            Text(loka.id)
                .font(.headline)
            MapView(escolha: loka.id).edgesIgnoringSafeArea(.all)
        }
    }
}

struct ContentView: View {

    // init(){
    //  UINavigationBar.appearance().backgroundColor = .lightGray

    //    }

    @State private var lokaData = [Geolokation]()
    @State private var searchText : String = ""

    var body: some View {

        NavigationView{

            VStack {
                SearchBar(text: $searchText)
                List {

                    ForEach (lokaData) {
                      item in
                        NavigationLink(destination: GeolokationDetail(loka: item)) {
                            HStack() {
                                Text(item.id)
                                    .font(.headline)
                                Text(item.date)
                                    .font(.footnote)
                            }
                        }

                    }.navigationBarTitle("GeoLOKAtion")

                }

                .onAppear(perform: loadData)


            }

        }

    }


}

extension ContentView
{
    func loadData() {

        guard let url = URL(string: "https://xxxx.com") else {
            return
        }

        let request = URLRequest(url: url)
        URLSession.shared.dataTask(with: request) { data, response, error in

            if let data = data {
                if let response_obj = try? JSONDecoder().decode([Geolokation].self, from: data) {
                    DispatchQueue.main.async {
                        self.lokaData = response_obj
                    }
                }
            }

        }.resume()
    }
}



struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

But I haven't been able to find a way to implement the search within the List.

I was planning to do something like:

ForEach(self.lokaData.filter {
    self.searchText.isEmpty ? true : $0.contains(self.searchText)
}, id: \.self) 

But it's not working. I'm missing some concept that I do not understand. Any ideas, please?

Thank you!

2
  • What’s not working? Give us the error. And remove the id argument from the ForEach. Geolokation already conforms to Identifiable, so you don’t need to manually dictate its id. Commented May 9, 2020 at 18:12
  • - the error its : "Value of type 'Geolokation' has no member 'contains'" Commented May 9, 2020 at 19:50

1 Answer 1

2

You are applying contains to an Struct, that is why you are getting that error, you should apply it to one of the properties of Geolokation, here is an example finding matches on latitud:

struct MyView: View {

    @State private var lokaData = [Geolokation.init(date: "date 1", id: "0", latitude: "1010", longitude: "2020", seq_number: "1234", accuracy: ""),
                                   Geolokation.init(date: "date 2", id: "1", latitude: "1020", longitude: "2030", seq_number: "5678", accuracy: ""),
                                   Geolokation.init(date: "date 3", id: "2", latitude: "1030", longitude: "2040", seq_number: "9101", accuracy: "")]
    var body: some View {
        VStack {
            //SearchBar
            ForEach(self.lokaData.filter {
                $0.latitude.contains(self.searchText)
            }, id: \.self) { item in
                Text(item.latitude)
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.