【发布时间】:2026-01-01 02:55:02
【问题描述】:
如何优化列表中的搜索。我有两千条记录。我不想通过 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)
}
}
}
}
【问题讨论】:
-
如果您不希望它实时显示,请不要将其放入 SwiftUI
View。工作(除了直接的用户交互之外的任何东西)应该保存在其他地方,例如 ViewModel 或某种类型的 Manager。听起来您正在尝试做一些超出 SwiftUI 包装器标准用途的事情,也许您应该看看其他方法,例如可以通过其他方式更新的NSFetch...选项或 dynamic predicates。
标签: list search filter swiftui combine