list - 优化列表搜索
问题描述
如何优化列表中的搜索。我有两千条记录。我不想通过 NSPredicate 进行搜索,因为我想在比较之前通过清理数字并减少字母的函数传递字段中的内容。您能否以某种方式延迟,使其不会立即搜索,而是在一段时间后或用户完成输入后搜索。我也听说过Combine之类的东西,但我不知道如何使用它。
歌集列表
import CoreData
import SwiftUI
struct SongbookView: View {
@State var searchText: String = ""
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(
entity: Song.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Song.number, ascending: true)]
) var songs: FetchedResults<Song>
var body: some View {
NavigationView{
VStack{
SearchBar(text: $searchText)
Spacer()
List(songs.filter({searchText.isEmpty ? true : removeNumber(str: $0.content!.lowercased()).contains(searchText.lowercased()) || String($0.number).contains(searchText)}), id:\.objectID) { song in
NavigationLink(destination: DetailView(song: song, isSelected: song.favorite)) {
HStack{
Text("\(String(song.number)). ") .font(.headline) + Text(song.title ?? "Brak tytułu")
if song.favorite {
Spacer()
Image(systemName: "heart.fill")
.accessibility(label: Text("To jest ulubiona pieśń"))
.foregroundColor(.red)
}
}.lineLimit(1)
}
}.id(UUID())
.listStyle(InsetListStyle())
.animation(.default)
}
.padding(.top, 10)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .principal) {
Text("Śpiewnik")
.font(.system(size: 20))
.bold()
}
}
}
}
func removeNumber(str: String) -> String {
var result = str
let vowels: Set<Character> = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
result.removeAll(where: { vowels.contains($0) })
return result
}
}
搜索栏
import SwiftUI
struct SearchBar: View {
@Binding var text: String
@State var isEditing = false
var body: some View {
HStack {
TextField("Szukaj ...", text: $text)
.padding(7)
.padding(.horizontal, 25)
.background(Color(.systemGray6))
.cornerRadius(8)
.overlay(
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding(.leading, 8)
if isEditing {
Button(action: {
self.text = ""
}) {
Image(systemName: "multiply.circle.fill")
.foregroundColor(.gray)
.padding(.trailing, 8)
}
}
}
)
.padding(.horizontal, 10)
.onTapGesture {
self.isEditing = true
}
if isEditing {
Button(action: {
self.isEditing = false
self.text = ""
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}) {
Text("Anuluj")
}
.padding(.trailing, 10)
.transition(.move(edge: .trailing))
.animation(.default)
}
}
}
}
解决方案
每当您更改您的文本SearchBar
(即您键入的每个字符)时,SongbookView
都会更新,因为您正在使用文本绑定。您想要的是仅在按回车键时进行一次更新。有很多方法可以做到这一点。执行此操作并保持绑定设置的一种快速方法是:
struct SearchBar: View {
@Binding var text: String
@State var txt: String = "" // <--- here a temp var
@State var isEditing = false
var body: some View {
HStack {
TextField("Szukaj ...", text: $txt) // <--- here
.onSubmit {
text = txt // <--- here only update on return press
}
.padding(7)
....
.onAppear {
txt = text // <--- here if needed
}
如果您使用的是 ios-14,请使用
TextField("Szukaj ...", text: $txt, onCommit: { // <--- here
text = txt // <--- here
})
推荐阅读
- delphi - 透明系列的 TeeChart 不透明标记 - 可能吗?
- android - Android Studio 3.2 - 加载小部件时出现问题
- vba - VBA认为某个键被按下
- android - 片段中的广播接收器称为 3 次仅发送一次
- android - 在 Appcelerator Titan 中将 blob 转换为位图图像
- vba - VBA如何在函数中替换“As Any”
- elasticsearch - 导入 Kibana 仪表板时出错:无法创建 Kibana 加载程序:创建 Kibana 客户端时出错
- c# - 仅在 VS 调试模式下解决 SQL 查询超时
- javascript - 如何解决网页错误消息:未捕获的引用错误
- python - 神经网络感知器算法 Sklearn