为什么Table的 'searchable' 属性不起作用?
我有一个文本输入框和一个表格。我想为我的表格设置筛选,使其显示包含搜索字符串的行数据。我为表格添加了“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()
}
}
}
解决方案
以下内容将修复你的代码。
- 将筛选后的数据放入表格中,而不是未筛选的数据
- 为了提高鲁棒性,使用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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。