Search 有没有一种方法可以在获取的结果初始化后用谓词修改它们?
我正在尝试为现有的CoreData应用程序(简单日志应用程序)构建搜索视图。 我将所有数据与CoreData一起存储,并通过@FetchRequest获取:Search 有没有一种方法可以在获取的结果初始化后用谓词修改它们?,search,core-data,swiftui,predicate,Search,Core Data,Swiftui,Predicate,我正在尝试为现有的CoreData应用程序(简单日志应用程序)构建搜索视图。 我将所有数据与CoreData一起存储,并通过@FetchRequest获取: @State private var searchPredicate: NSPredicate? = NSPredicate(format: "title contains[c] %@", "") @FetchRequest( entity: Item.entity(), sortDescriptors: [NSSortDescripto
@State private var searchPredicate: NSPredicate? = NSPredicate(format: "title contains[c] %@", "")
@FetchRequest( entity: Item.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Item.title, ascending: true)],
predicate: NSPredicate(format: "title contains[c] %@", "h")
)
var items: FetchedResults<Item>
然后我创建了一个新类“Searchbar”,它在searchview中被调用,应该根据搜索字段的输入创建一个谓词,然后将其作为绑定传递给父级,然后根据该谓词可以显示正确的项
在searchview中调用VStack顶部的搜索栏:
SearchBar(text: $searchText, predicate: $searchPredicate)
绑定根据“搜索栏”中的用户输入而变化:
到目前为止还不错
我现在遇到的问题是,我们有一个谓词可以工作,但不能在定义中的@Fetchrequest中调用,因为它会在初始化之前被调用
@State private var searchPredicate: NSPredicate? = NSPredicate(format: "title contains[c] %@", "")
@FetchRequest(
entity: Item.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Item.title, ascending: true)
],
predicate: searchPredicate
) var items: FetchedResults<Item>
@State private var searchPredicate:NSPredicate?=NSPredicate(格式:“标题包含[c]%@”,“”)
@获取请求(
实体:Item.entity(),
sortDescriptors:[
NSSortDescriptor(键路径:\Item.title,升序:true)
],
谓词:搜索谓词
)变量项:FetchedResults
这给了我一个错误,即在self可用之前无法运行属性初始值设定项,这是合乎逻辑的,但让我感到疑惑,并让我回到我的问题:是否有方法在初始化后使用谓词修改获取的结果?
我还尝试过在ForEach()语句中对获取的结果调用谓词相关的方法,但它们似乎都不起作用
如果有任何问题,请随时提问
有没有一种方法可以在获取结果之后使用谓词修改它们
是否已初始化
嗯。。。不,不是以您尝试这样做的方式,即使您尝试使用NSFetchRequest实例(即引用)创建它,并允许以后更改谓词,也不会起作用,因为SwiftUI的FetchRequest存储提供的fetch请求的副本(或使用提供的参数创建自己的副本)。。。所以,没有。但是
您可以将提供获取请求参数的视图分解为构造获取请求并显示结果的视图
下面是该方法的一个演示(它的重要部分),它使您能够使用不同的动态更改谓词获得结果:
struct MasterView: View {
@State var predicate: NSPredicate? = nil
var body: some View {
VStack {
Button(action: { // button just for demo
self.predicate = NSPredicate(format: "title contains[c] %@", "h")
}, label: { Text("Filter") })
ResultView(predicate: self.predicate)
}
}
}
struct ResultView: View {
@FetchRequest
var events: FetchedResults<Event>
@Environment(\.managedObjectContext)
var viewContext
init(predicate: NSPredicate?) {
let request: NSFetchRequest<Event> = Event.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(keyPath: \Event.timestamp, ascending: true)]
if let predicate = predicate {
request.predicate = predicate
}
_events = FetchRequest<Event>(fetchRequest: request)
}
var body: some View {
List {
ForEach(events, id: \.self) { event in
...
struct主视图:视图{
@状态变量谓词:NSPredicate?=nil
var body:一些观点{
VStack{
按钮(操作:{//按钮仅用于演示
self.predicate=NSPredicate(格式:“标题包含[c]@”,“h”)
},标签:{Text(“Filter”)})
结果视图(谓词:self.predicate)
}
}
}
结构结果视图:视图{
@获取请求
var事件:FetchedResults
@环境(\.managedObjectContext)
var viewContext
init(谓词:NSPredicate?){
let请求:NSFetchRequest=Event.fetchRequest()
request.sortDescriptors=[NSSortDescriptor(keyPath:\Event.timestamp,升序:true)]
如果let谓词=谓词{
request.predicate=谓词
}
_events=FetchRequest(FetchRequest:request)
}
var body:一些观点{
名单{
ForEach(events,id:\.self){event in
...
我决定发布Asperi提供的完美答案的完整工作版本,因为我在其他任何地方都没有找到工作解决方案
struct MasterView: View {
@State var predicate: NSPredicate? = nil
@State private var searchText = ""
var body: some View {
VStack {
TextField("Search", text: $searchText, onEditingChanged: {_ in
self.predicate = NSPredicate(format: "title contains[c] %@", "\(self.searchText)")
print("THE PREDICATE: \(String(describing: self.predicate))")
}, onCommit: {
print("onCommit")
}).foregroundColor(.primary)
SearchView(predicate: self.predicate)
}
}
}
以及SearchView:
List {
ForEach(Items) { Item in
ListViewItem(title: Item.title!, subTitle: Item.subTitle!, createdAt: "\(Item.createdAt!)")
}
}
struct SearchView: View {
@State private var searchText = ""
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest var items: FetchedResults<Item>
init(predicate: NSPredicate?) {
let request: NSFetchRequest<Item> = Item.fetchRequest() as! NSFetchRequest<Item>
request.sortDescriptors = [NSSortDescriptor(keyPath: \Item.title, ascending: true)]
if let predicate = predicate {
request.predicate = predicate
}
_items = FetchRequest<Item>(fetchRequest: request)
}
var body: some View {
VStack {
List {
...
struct SearchView:View{
@国家私有var searchText=“”
@环境(\.managedObjectContext)变量managedObjectContext
@FetchRequest变量项:FetchedResults
init(谓词:NSPredicate?){
让请求:NSFetchRequest=Item.fetchRequest()作为!NSFetchRequest
request.sortDescriptors=[NSSortDescriptor(键路径:\Item.title,升序:true)]
如果let谓词=谓词{
request.predicate=谓词
}
_items=FetchRequest(FetchRequest:request)
}
var body:一些观点{
VStack{
名单{
...
作为@Asperi回答的内容(Swift 5.4 Xcode 12.5)的一个小更新,在结果视图中,您现在可以执行以下操作:
var fetchRequest: FetchRequest<Event>
init(predicate: NSPredicate?) {
fetchRequest = FetchRequest<Event>(entity:
Event.entity(), sortDescriptors: [NSSortDescriptor(keyPath:
\Event.timestamp, ascending: true)], predicate: predicate)
}
好的,谢谢你的回答,我想这已经接近我想要实现的目标了。现在,当调用ResultView时,谓词会随之传递,然后事件会被排序。但是我仍然面临无法动态传递谓词的问题。别介意我刚刚让它工作了,你的代码工作得很好!!非常感谢你r您的快速回复。Jannis,您是否还在某处有一个可用的示例?您发布的示例不完整,我无法使其运行。我想从您的示例中学习,因为我现在正在努力在SwiftUI中创建动态谓词
var fetchRequest: FetchRequest<Event>
init(predicate: NSPredicate?) {
fetchRequest = FetchRequest<Event>(entity:
Event.entity(), sortDescriptors: [NSSortDescriptor(keyPath:
\Event.timestamp, ascending: true)], predicate: predicate)
}
public init(entity: NSEntityDescription, sortDescriptors: [NSSortDescriptor], predicate: NSPredicate? = nil, animation: Animation? = nil)