How to implement Search for Table

How to filter table content based on search text, sample code:






struct Person: Identifiable {

    let givenName: String

    let familyName: String

    let index: String

    let id = UUID()

}

    @State private var searchText: String = ""

@State private var people = [

    Person(givenName: "Juan", familyName: "Chavez", index: "0"),

    Person(givenName: "Mei", familyName: "Chen", index: "1"),

    Person(givenName: "Tom", familyName: "Clark", index: "2, id: 2"),

    Person(givenName: "Gita", familyName: "Kumar", index: "3, id: 3"),

]

@State private var sortOrder = [KeyPathComparator(\Person.givenName)]

    @State private var selection : Person.ID?

    var body: some View {


    Table(people, selection: $selection, sortOrder: $sortOrder) {

        TableColumn("Given Name", value: \.givenName)

        

        TableColumn("Family Name", value: \.familyName)

    }

    .onChange(of: sortOrder) {

        people.sort(using: $0)

    }

    .searchable(text: $searchText)

}

}
Answered by Claude31 in 710951022

Do this (you can remove index, not needed):

struct TestTable: View {
    
    struct Person: Identifiable {
        let givenName: String
        let familyName: String
        let id = UUID() 
    }
    
    @State private var people = [
        Person(givenName: "Juan", familyName: "Chavez"),  // , index: "0"), //, id: 0),
        Person(givenName: "Mei", familyName: "Chen"),  // , index: "1"), //, id: 1),
        Person(givenName: "Tom", familyName: "Clark"),  // , index: "2"), //, id: 2),
        Person(givenName: "Gita", familyName: "Kumar")  // , index: "3") //, id: 3),
    ]
    
    @State private var sortOrder = [KeyPathComparator(\Person.givenName)]
    
    @State private var searchText = ""
    
    @State private var selection = Set<Person.ID>()
    
    var searchResults : [Person] {
        if searchText.isEmpty {
            return people
        } else {
            return people.filter {$0.givenName == searchText }   
            // You could filter with contains 
            // people.filter {$0.givenName.lowercased().contains(searchText.lowercased()) }
        }
    }
    
    var body: some View {
        
        Button(action: {
            
            let arrayindex = self.selection
            let item = people.filter() { arrayindex.contains($0.id) }
            print(item.first?.givenName ?? "")

            // If you need the row:
            var newIndex : Int?
            for (index, elem) in people.enumerated() {
                if arrayindex.contains(elem.id) { newIndex = index; break }
            }
            print("index in table is", newIndex == nil ? "unknown" : String(newIndex!))
        }){
            Label("Print Array Items", systemImage: "doc.text.magnifyingglass")
        }

       TextField("name", text: $searchText)  // <<-- ADDED
            .frame(width: 200, alignment: .center)

        Table(searchResults, selection: $selection, sortOrder: $sortOrder) {  // <<-- CHANGED to searchResults
            TableColumn("Given Name", value: \.givenName)
            TableColumn("Family Name", value: \.familyName)
            
        }
        .onChange(of: sortOrder) {
            people.sort(using: $0)
        }
        .searchable(text: $searchText)
        
    }
    
}
Accepted Answer

Do this (you can remove index, not needed):

struct TestTable: View {
    
    struct Person: Identifiable {
        let givenName: String
        let familyName: String
        let id = UUID() 
    }
    
    @State private var people = [
        Person(givenName: "Juan", familyName: "Chavez"),  // , index: "0"), //, id: 0),
        Person(givenName: "Mei", familyName: "Chen"),  // , index: "1"), //, id: 1),
        Person(givenName: "Tom", familyName: "Clark"),  // , index: "2"), //, id: 2),
        Person(givenName: "Gita", familyName: "Kumar")  // , index: "3") //, id: 3),
    ]
    
    @State private var sortOrder = [KeyPathComparator(\Person.givenName)]
    
    @State private var searchText = ""
    
    @State private var selection = Set<Person.ID>()
    
    var searchResults : [Person] {
        if searchText.isEmpty {
            return people
        } else {
            return people.filter {$0.givenName == searchText }   
            // You could filter with contains 
            // people.filter {$0.givenName.lowercased().contains(searchText.lowercased()) }
        }
    }
    
    var body: some View {
        
        Button(action: {
            
            let arrayindex = self.selection
            let item = people.filter() { arrayindex.contains($0.id) }
            print(item.first?.givenName ?? "")

            // If you need the row:
            var newIndex : Int?
            for (index, elem) in people.enumerated() {
                if arrayindex.contains(elem.id) { newIndex = index; break }
            }
            print("index in table is", newIndex == nil ? "unknown" : String(newIndex!))
        }){
            Label("Print Array Items", systemImage: "doc.text.magnifyingglass")
        }

       TextField("name", text: $searchText)  // <<-- ADDED
            .frame(width: 200, alignment: .center)

        Table(searchResults, selection: $selection, sortOrder: $sortOrder) {  // <<-- CHANGED to searchResults
            TableColumn("Given Name", value: \.givenName)
            TableColumn("Family Name", value: \.familyName)
            
        }
        .onChange(of: sortOrder) {
            people.sort(using: $0)
        }
        .searchable(text: $searchText)
        
    }
    
}
How to implement Search for Table
 
 
Q