初始化后,是否可以用谓词修改获取的结果? [英] Is there a way to modify fetched results with a predicate after they are initialized?

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

问题描述

我正在尝试为现有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...

我现在遇到的问题是,我们有一个谓词有效,但不能在内部调用

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.

推荐答案


是否有一种方法可以在谓词$之后修改带有谓词的获取结果b $ b是否已初始化?

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

嗯...不,不是您尝试这样做的方式,即使您d尝试使用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天全站免登陆