为什么Table的 'searchable' 属性不起作用?

移动开发 2026-07-10

我有一个文本输入框和一个表格。我想为我的表格设置筛选,使其显示包含搜索字符串的行数据。我为表格添加了“searchable”属性,但似乎不起作用。我不明白为什么?

这是我的代码:

import SwiftUI
import Foundation
//identify structure for array and table
struct myItems: Identifiable {
    let id = UUID()
    let myItemStr: String
    // A helper property to check if any part of the row data contains the search string
    func contains(_ searchText: String) -> Bool {
        let lowercasedSearch = searchText.lowercased()
        return myItemStr.lowercased().contains(lowercasedSearch)
    }
}
struct ContentView: View {
    //string for filter
    @State private var searchQuery: String = ""
    //computed property to filter results dynamically
    var searchResults: [myItems] {
            if searchQuery.isEmpty {
                return myItemsArray
            } else {
                return myItemsArray.filter { $0.contains(searchQuery) }
            }
        }
    //variable for title in the table
    @State private var myTableTitleStr: String = "My Items"
    //set single selection for table
    @State private var selectedItemID: myItems.ID?
    //array for filling table
    @State private var myItemsArray = [myItems(myItemStr: "Item01"), myItems(myItemStr: "Item02"), myItems(myItemStr: "Item03")]

    var body: some View {
        VStack {
            //myTextField
            TextField("Select Item", text: $searchQuery)
            //myTable
            Table(myItemsArray, selection: $selectedItemID) {
                TableColumn(myTableTitleStr, value: \.myItemStr)
            }
            //Add the searchable modifier
            .searchable(text: $searchQuery, placement: .automatic, prompt: "Search Items")
            //print selected row
            .onChange(of: selectedItemID) { newSelection in
                if let newSelection = myItemsArray.first(where: {$0.id == selectedItemID}) {
                    print(newSelection.myItemStr)
                }
            }
            .padding()
            .frame(width: 400.0, height: 400.0)
        }
    }
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
}

解决方案

以下内容将修复你的代码。

  1. 将筛选后的数据放入表格中,而不是未筛选的数据
  2. 为了提高鲁棒性,使用localizedCaseInsensitiveContains方法来检查一个字符串是否包含在另一个字符串中,例如 "Bonjor".localizedCaseInsensitiveContains("hello") 将返回true 3.(额外提示):为清晰起见,遵循Swift的命名约定,对结构体名称使用大驼峰命名法(Pascal Case):如MyItem;表示单个项时,使用单数形式。
import SwiftUI
import Foundation
//identify structure for array and table
struct myItems: Identifiable {  // Confusing name, maybe call it MyItem rather than myItems plural, and in correct case
    let id = UUID()
    let myItemStr: String
    // A helper property to check if any part of the row data contains the search string
    func contains(_ searchText: String) -> Bool {
        // let lowercasedSearch = searchText.lowercased()
        // return myItemStr.lowercased().contains(lowercasedSearch)
        myItemStr.localizedCaseInsensitiveContains(searchText)
    }
}
struct ContentView: View {
    //string for filter
    @State private var searchQuery: String = ""
    //computed property to filter results dynamically
    var searchResults: [myItems] {
            if searchQuery.isEmpty {
                return myItemsArray
            } else {
                return myItemsArray.filter { $0.contains(searchQuery) }
            }
        }
    //variable for title in the table
    @State private var myTableTitleStr: String = "My Items"
    //set single selection for table
    @State private var selectedItemID: myItems.ID?
    //array for filling table
    @State private var myItemsArray = [myItems(myItemStr: "Item01"), myItems(myItemStr: "Item02"), myItems(myItemStr: "Item03")]

    var body: some View {
        VStack {
            //myTextField
            TextField("Select Item", text: $searchQuery)
            //myTable
            // Table(myItemsArray, selection: $selectedItemID) {
            // Put the sorted list in the table not unsorted
            Table(searchResults, selection: $selectedItemID) {
                TableColumn(myTableTitleStr, value: \.myItemStr)
            }
            //Add the searchable modifier
            .searchable(text: $searchQuery, placement: .automatic, prompt: "Search Items")
            //print selected row
            .onChange(of: selectedItemID) { newSelection in
                if let newSelection = myItemsArray.first(where: {$0.id == selectedItemID}) {
                    print(newSelection.myItemStr)
                }
            }
            .padding()
            .frame(width: 400.0, height: 400.0)
        }
    }
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章