Dam*_*zzi 1 predicate swift-data swiftui
我正在尝试使用带有搜索栏的 SwiftData 框架创建一个视图,用户可以在其中输入飞机的注册信息并动态更新列表。但首先我不确定我是否正确执行(我在网上找不到太多示例)并且收到错误:
通用结构“ForEach”要求“Query<Aircraft, [Aircraft]>”符合“RandomAccessCollection”
struct AirplanePick: View {
@State var addNewPlane = false
@Environment (\.modelContext) var mc
@Binding var planePick: Aircraft?
let dm: DataManager
@Environment(\.presentationMode) var presentationMode
@State var searchTerm: String = ""
var filterPlanes : Query<Aircraft, [Aircraft]>{
var predicate: Predicate<Aircraft>?
if !searchTerm.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
predicate = .init(#Predicate { $0.registration.contains(searchTerm) })
}
return Query(filter: predicate, sort: \.registration)
}
var body: some View {
List {
Text("planes are \(planes.count)")
ForEach(filterPlanes, id: \.self){ plane in
Button {
planePick = plane
self.presentationMode.wrappedValue.dismiss()
} label: {
HStack{
VStack(alignment: .leading, content: {
Text("Registration").foregroundStyle(.secondary).font(.subheadline)
Text(plane.registration).bold()
})
Spacer()
VStack(alignment: .trailing, content: {
Text("Type").foregroundStyle(.secondary).font(.subheadline)
Text(plane.type ?? "")
})
}
}
}
.onDelete { IndexSet in
IndexSet.forEach { index in
let airplane = planes[index]
mc.delete(airplane)
}
}
}.toolbar {
NavigationLink("Add New") {
AddNewAirplane()
}
}
.searchable(text: $searchTerm)
}
}
Run Code Online (Sandbox Code Playgroud)
飞机型号如下:
@Model
class Aircraft{
@Attribute(.unique) var idAircraft: UUID = UUID()
var flight: Flight?
var registration: String
var category: String
var type: String?
var maxWeigth: String?
var maker: String?
var model: String?
var classOF: String?
var oper: String?
var owner: String?
var msn: String?
var note: String?
var aerobatic:Int?
var engineType:String?
var complex: Int?
var efis: Int?
var hightPerf: Int?
var military: Int?
var pressurize:Int?
var radialEngine:Int?
var tailwheel: Int?
var turbocharger: Int?
var ambphibian: Int?
var retractGear: Int?
var year: String?
init(idAircraft: UUID, registration: String, category: String, type: String? = nil, maxWeigth: String? = nil, maker: String? = nil, model: String? = nil, classOF: String? = nil, oper: String? = nil, owner: String? = nil, msn: String? = nil, note: String? = nil, aerobatic: Int? = nil, engineType: String? = nil, complex: Int? = nil, efis: Int? = nil, hightPerf: Int? = nil, military: Int? = nil, pressurize: Int? = nil, radialEngine: Int? = nil, tailwheel: Int? = nil, turbocharger: Int? = nil, ambphibian: Int? = nil, retractGear: Int? = nil, year: String? = nil) {
self.idAircraft = idAircraft
self.registration = registration
self.category = category
self.type = type
self.maxWeigth = maxWeigth
self.maker = maker
self.model = model
self.classOF = classOF
self.oper = oper
self.owner = owner
self.msn = msn
self.note = note
self.aerobatic = aerobatic
self.engineType = engineType
self.complex = complex
self.efis = efis
self.hightPerf = hightPerf
self.military = military
self.pressurize = pressurize
self.radialEngine = radialEngine
self.tailwheel = tailwheel
self.turbocharger = turbocharger
self.ambphibian = ambphibian
self.retractGear = retractGear
self.year = year
}
}
Run Code Online (Sandbox Code Playgroud)
我的第一个建议是不要Query像这样使用,因为这意味着大量的数据库访问,所以除非您有大量的持久对象,否则最好在内存中进行过滤
@Query(sort: \.registration) var objects: [AirCraft]
//...
var filtered: [Aircraft] {
guard searchText.isEmpty == false else { return objects }
return objects.filter { $0.registration.contains(searchTerm)}
}
Run Code Online (Sandbox Code Playgroud)
如果您确实想使用谓词进行过滤,则应该创建一个新视图,并在每次更改时将谓词传递给该视图。
@State private var predicate: Predicate<AirCraft> = .true
var body: some View {
//...
AirCraftListView(predicate: predicate)
}
.searchable(text: $searchTerm)
.onChange(of: searchTerm) { old, new in
guard new.isEmpty == false, old != new else { return }
predicate = #Predicate<AirCraft> {
$0.registration.contains(new)
}
}
Run Code Online (Sandbox Code Playgroud)
然后在列表视图中
struct AirCraftListView: View {
@Query(sort: \.registration) var objects: [AirCraft]
init(predicate: Predicate< AirCraft >) {
_objects = Query(filter: predicate)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1134 次 |
| 最近记录: |