I would like to use the search bar to filter the following data.
I also used bindings and identifications, so it got pretty complex pretty quickly. I would be grateful for any help. All of the code is below.
import SwiftUI
// First navigationbar
struct ContentView: View {
var body: some View {
NavigationView {
List {
NavigationLink(destination: SecondaryView()) {
Text("Customer")
.font(.system(size: 13))
}
}
.padding(.top, 12)
SecondaryView()
}
}
}
// Second navigationbar
struct SecondaryView: View {
@State private var search = ""
@State private var customerData = [
ListView("1035", "John", "Doe"),
ListView("10213", "Jane", "Smith")
]
var body: some View {
NavigationView {
List {
HStack {
Image(systemName: "magnifyingglass")
TextField("Search ", text: $search)
}
.padding(.bottom, 3)
ForEach($customerData) { $i in
NavigationLink(destination: CustomerView(number: $i.number, firstName: $i.firstName, lastName: $i.lastName)) {
Text(i.number)
Text(" ")
Text(i.firstName)
.foregroundColor(.gray)
Text(" ")
Text(i.lastName)
.foregroundColor(.gray)
}
}
}
}
}
}
// Id for second navigationbar
struct ListView: Identifiable {
let id = UUID()
var number: String
var firstName: String
var lastName: String
init(_ number: String, _ firstName: String, _ lastName: String) {
self.number = number
self.firstName = firstName
self.lastName = lastName
}
}
// Third view (empty)
struct CustomerView: View {
@Binding var number: String
@Binding var firstName: String
@Binding var lastName: String
var body: some View {
Text("")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I used the following line for the search, but since I now want to filter out several words from an array with bindings and ids, this method no longer works.
ForEach(customerNumber.filter({ (i: String) -> Bool in return i.hasPrefix(searchText) || searchText == "" }), id: \.self) { i in
CodePudding user response:
Here is your solution:
struct ContentView: View {
@StateObject private var viewModel = SearchViewModel()
@State private var query = ""
let suggestions: [String] = [
"Swift", "SwiftUI", "Obj-C"
]
var body: some View {
NavigationView {
List() {
// Your code..
}
.navigationTitle("Search")
.searchable(text: $query) {
ForEach(suggestions, id: \.self) { suggestion in
Text(suggestion)
.searchCompletion(suggestion)
}
}
.onChange(of: query) { newQuery in
async { await viewModel.search(matching: query) }
}
}
}
}
CodePudding user response:
In case you don't want it in the titlebar, do that:
import SwiftUI
struct SearchBar : UIViewRepresentable {
@Binding var text : String
func searchBar(_ searchBar: UISearchBar,
textDidChange searchText: String) {
text = searchText
}
}
func makeCoordinator() -> SearchBar.Cordinator {
return Cordinator(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
}
}
import SwiftUI
struct ContentView: View {
let names = [“Raju”, “Ghanshyam”, “Baburao Ganpatrao Apte”, “Anuradha”, “Kabira”, “Chaman Jhinga”, “Devi Prasad”, “Khadak Singh”]
@State private var searchTerm : String = “”
var body: some View {
NavigationView{
List {
SearchBar(text: $searchTerm)
ForEach(self.names.filter{
self.searchTerm.isEmpty ? true : $0.localizedStandardContains(self.searchTerm)
}, id: \.self) { name in
Text(name)
}
}
.navigationBarTitle(Text(“Search Bar”))
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}