swift - 用于过滤列表内容的搜索栏 (macOS Big Sur)
问题描述
我正在尝试通过搜索栏实现对数据模型的搜索。
我的数据模型是以下结构:
struct NoteItem: Codable, Hashable, Identifiable {
let id: UUID
var text: String
var date = Date()
var dateText: String {
let df = DateFormatter()
df.dateFormat = "EEEE, MMM d yyyy, h:mm a"
return df.string(from: date)
}
var tags: [String] = []
var filename: String = ""
var changed: Bool = false
}
应用程序迭代数据模型上的每个元素并填充一个列表,其中 aNavigationLink
有两个Text
:一个带有 a 的第一行TextEditor
,另一个带有datamodel.dateText
. 列表中的每个项目都指向另一个视图,在该视图中TextEditor
显示完整datamodel.text
我要添加的搜索将仅在datamodel.text
. 代码如下:
struct AllNotes: View {
@EnvironmentObject private var data: DataModel
...
var body: some View {
NavigationView {
List(data.notes) { note in
NavigationLink(
destination: NoteView(note: note, text: note.text),
tag: note.id,
selection: $selectedNoteId
) {
VStack(alignment: .leading) {
Text(getTitle(noteText: note.text)).font(.body).fontWeight(.bold)
Text(note.dateText).font(.body).fontWeight(.light)
}
.padding(.vertical, 10)
}
}
.listStyle(InsetListStyle())
.frame(minWidth: 250, maxWidth: .infinity)
}
.toolbar {
ToolbarItem(placement: .automatic) {
TextField("Search...", text: $searchText)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(minWidth: 200)
}
}
}
}
搜索栏是工具栏中的 TextField。
在 iOS 中,过去,我做过类似的事情:
List(ListItems.filter({ searchText.isEmpty ? true : $0.name.contains(searchText) })) { item in
Text(item.name)
}
但是鉴于搜索栏是工具栏中的一个项目,并且我需要从数据模型中的所有文本中搜索过滤/重新填充列表,而不仅仅是列表,我什至该如何开始呢?如何过滤它?我需要填充一个新数组吗?如何访问搜索栏上的文本?它$searchText
在我发布的代码中吗?我表演data.filter
吗?
我已经没有尝试的想法了。
谢谢你。
编辑:
我有这种工作,但请注意。它弄乱了NavigationLink
显示的方式,它在文本之前添加了随机空格。
代码:
var body: some View {
NavigationView {
List {
ForEach(data.notes.filter { $0.text.contains(searchText) || searchText.isEmpty }) { note in
NavigationLink(
destination: NoteView(note: note, text: note.text),
tag: note.id,
selection: $selectedNoteId
) {
VStack(alignment: .leading) {
Text(getTitle(noteText: note.text)).font(.body).fontWeight(.bold)
Text(note.dateText).font(.body).fontWeight(.light)
}
.padding(.vertical, 10)
}
}
.listStyle(InsetListStyle())
.frame(minWidth: 250, maxWidth: .infinity)
.alert(isPresented: $showAlert, content: {
alert
})
Text("Create a new note...")
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
解决方案
这是编辑的答案,因此人们不会抱怨:
var body: some View {
NavigationView {
List(data.notes.filter { searchText.isEmpty ? true : $0.text.localizedCaseInsensitiveContains(searchText) }) { note in
NavigationLink(
destination: NoteView(note: note, text: note.text),
tag: note.id,
selection: $selectedNoteId
) {
VStack(alignment: .leading) {
Text(getTitle(noteText: note.text)).font(.body).fontWeight(.bold)
Text(note.dateText).font(.body).fontWeight(.light)
}
.padding(.vertical, 10)
}
}
.listStyle(InsetListStyle())
.frame(minWidth: 250, maxWidth: .infinity)
.alert(isPresented: $showAlert, content: {
alert
})
}
推荐阅读
- free-jqgrid - 使用 jqGrid 我需要显示一个基于 UserData Parm 的隐藏列
- amazon-web-services - AWS CDK S3 部署错误 - 上传的文件必须是非空 zip
- apache-spark - 如何阻止pyspark中的时间戳丢弃尾随零
- c# - 如何在 C# 中以 JSON 格式访问数组中的项目
- docker - 为什么 docker 容器只能使用 0.0.0.0 连接?
- string - 拆分文件名 - 奇怪的行为
- mysql - mysql存储函数返回总数
- javascript - 将 AudioBuffer 从 JavaScript (Fload32Array) 转换为 C# (ByteArray)
- python - Pytorch 上的 1D CNN:mat1 和 mat2 形状不能相乘(10x3 和 10x2)
- laravel-blade - 如何禁用 Laravel 刀片中的 {{ }} 命令之一?