有没有办法在初始化后用谓词修改获取的结果? [英] Is there a way to modify fetched results with a predicate after they are initialized?

查看:22
本文介绍了有没有办法在初始化后用谓词修改获取的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为现有的 CoreData 应用程序(简单的日志记录应用程序)构建搜索视图.我将所有数据存储在 CoreData 中,并使用 @FetchRequest 获取:

I am trying to build a search view for an existing CoreData app (simple logging app). I have all the data stored with CoreData and is fetched with the @FetchRequest:

@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>

它现在只获取通过谓词测试的项目,在这种情况下,这些项目都是包含h"的项目.然后我将结果显示在 SearchView 主体的列表中:

It now only fetches the items that pass the predicate test which in this case are all the ones that contain an "h". I then display the results in a List in the body of the SearchView:

List {

  ForEach(Items) { Item in

      ListViewItem(title: Item.title!, subTitle: Item.subTitle!, createdAt: "(Item.createdAt!)")

     }
}

然后我创建了一个新类Searchbar",它在搜索视图中被调用,它应该根据搜索字段的输入创建一个谓词,然后将它作为绑定传递给父级,然后基于该谓词可以显示正确的项目.

I then created a new class "Searchbar" which is called in the searchview and is supposed to create a predicate based on the input of the search field and then pass it on as a Binding to the parent where then based on that predicate the correct items can be displayed.

在搜索视图中调用 VStack 顶部的搜索栏:

Calling the searchbar at the top of a VStack in the searchview:

SearchBar(text: $searchText, predicate: $searchPredicate)

绑定会根据用户在searchBar"中的输入而变化:

The Bindings change depending on the user input in the "searchBar":

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    text = searchText
    predicate = NSPredicate(format: "title contains[c] %@", searchText)

 }

到目前为止一切都很好...

So far so good...

我现在遇到的问题是我们有一个有效的谓词,但不能在定义中的 @Fetchrequest 中调用,因为它会在初始化之前被调用.

The problem I have now run into is that we have a predicate that works but can't be called within the @Fetchrequest in the definitions since it would be called before its initialized.

@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>

这给了我一个错误,即在 self 可用之前无法运行属性初始值设定项,这是合乎逻辑的,但让我想知道并让我回到我的问题:有没有办法用谓词修改获取的结果初始化之后?

This gives me the error that the property initializer can't be run before self is available which is logical but makes me wonder and brings me back to my question: Is there a way to modify fetched results with a predicate after they are initialized?

我还尝试在 ForEach() 语句中对获取的结果调用谓词相关的方法,但它们似乎都不起作用.

I have also tried calling predicate related methods on the fetched results in the ForEach() statement but none of them seemed to have worked.

如果有任何问题,请随时提出.

If there are any questions please do not hesitate to ask.

推荐答案

有没有办法在获取的结果之后用谓词修改它们初始化了吗?

Is there a way to modify fetched results with a predicate after they are initialized?

嗯...不,不是你尝试这样做的方式,即使你尝试使用 NSFetchRequest 实例创建它,它是引用,并允许稍后更改谓词,那也行不通,因为 SwiftUI 的 FetchRequest 存储提供的获取请求的副本(或使用提供的参数创建自己的)......所以,不.但是...

Well... no, not in the way you try to do this, and even if you'd try to create it with NSFetchRequest instance, which is reference, and allows to change predicate later, that wouldn't work, because SwiftUI's FetchRequest stores copy of provided fetch request (or creates own with provided parameters)... so, no. But...

您可以将提供获取请求参数的视图与构建获取请求并显示结果的视图分开.

You can break apart view providing fetch request parameters with view constructing fetch request and showing result.

这是一个方法演示(其中的重要部分),它使您可以使用不同的动态更改谓词获得结果:

Here is a demo of approach (important part of it) which gives you possibility to get results with different dynamically changed predicates:

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
    ...

这篇关于有没有办法在初始化后用谓词修改获取的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆