gpt4 book ai didi

swiftui - 如何根据用户输入使用新谓词重新运行@FetchRequest?

转载 作者:行者123 更新时间:2023-12-02 11:58:41 28 4
gpt4 key购买 nike

我有一个使用 @FetchRequest 显示来自 CoreData 的对象的列表,我想为用户提供一个栏按钮,单击该按钮将过滤显示的列表。如何更改 @FetchRequest 谓词并动态重新运行它以使用过滤后的项目重建列表?

struct EmployeeListView : View {
@FetchRequest(
entity: Department.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Department.name, ascending: false)],
)
var depts: FetchedResults<Department>
@Environment(\.managedObjectContext) var moc

var body: some View {
NavigationView {
List {
ForEach(depts, id: \.self) { dept in
Section(header: Text(dept.name)) {
ForEach(dept.employees, id: \.self) { emp in
Text(emp.name)
}
}
}
}
.navigationBarTitle("Employees")
}
}

}

我知道如何提供过滤器,但我不知道如何更改属性包装器谓词并重新运行获取请求。

最佳答案

您可以根据获取谓词中的绑定(bind)来更改结果,但对于 Bool vars,我发现这很难做到。原因是,在 CoreData 中测试 Bool 的谓词类似于 NSPredicate(format: "myAttrib == YES")而你的 Bool 绑定(bind)变量将为 true 或 false,而不是 YES 或 NO...所以如果你 NSPredicate(format: "%K ==%@", #keypath(Entity.seeMe), seeMe.wrappedValue) ,这将永远是错误的。也许我错了,但这就是我的经历。

您可以更轻松地根据字符串数据过滤您的提取。但它的工作方式与下面的示例略有不同,因为您需要在 View 的 init() 中运行您的提取,如下所示:

 @Binding var searchTerm:String
var fetch: FetchRequest<Entity>
var rows: FetchedResults<Entity>{fetch.wrappedValue}


init(searchTerm:Binding<String>) {
self._searchTerm = searchTerm
self.fetch = FetchRequest(entity: Entity.entity(), sortDescriptors: [], predicate: NSPredicate(format: "%K == %@", #keyPath(Entity.attribute),searchTerm.wrappedValue))
}

要完成您所描述的任务,请单击栏按钮项从而切换 Bool,我建议使用以下示例:

此示例将在不更改获取谓词的情况下实现您的目标。它使用逻辑根据数据模型中的条目和 @State 变量的值来决定是否显示一行数据。


import SwiftUI
import CoreData
import Combine

struct ContentView: View {

@Environment(\.managedObjectContext) var viewContext
@State var seeMe = false

@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Entity.attribute, ascending: true)],
animation: .default)
var rows: FetchedResults<Entity>

var body: some View {

NavigationView {
VStack {


ForEach(self.rows, id: \.self) { row in

Group() {
if (self.validate(seeMe: row.seeMe)) {
Text(row.attribute!)
}
}

}
.navigationBarItems(leading:
Button(action: {
self.seeMe.toggle()
}) {
Text("SeeMe")
}
)

Button(action: {
Entity.create(in: self.viewContext, attribute: "See Me item", seeMe: true)
}) {
Text("add seeMe item")
}

Button(action: {
Entity.create(in: self.viewContext, attribute: "Dont See Me item", seeMe: false)
}) {
Text("add NON seeMe item")
}

}
}

}

func validate(seeMe: Bool) -> Bool {
if (self.seeMe && seeMe) {
return true
} else if (!self.seeMe && !seeMe ){
return true
} else {
return false
}
}
}


extension Entity {
static func create(in managedObjectContext: NSManagedObjectContext,
attribute: String,
seeMe: Bool
){

let newEvent = self.init(context: managedObjectContext)
newEvent.attribute = attribute
newEvent.seeMe = seeMe
}

static func save(in managedObjectContext: NSManagedObjectContext) {
do {
try managedObjectContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}

}

要使用此示例,请创建一个核心数据模型,其中包含一个名为“Entity”的实体和两个属性,一个名为“attribute”,为字符串,另一个名为“seeMe”,为 Bool。然后运行它,按按钮创建两种类型的数据,然后单击顶部的栏按钮项选择要显示的数据。

我不是最漂亮的示例,但它应该演示您想要完成的功能。

关于swiftui - 如何根据用户输入使用新谓词重新运行@FetchRequest?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57833813/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com