在swiftUI中更改谓词时重新加载FetchedResults [英] reload FetchedResults when changing the predicate in swiftUI

查看:47
本文介绍了在swiftUI中更改谓词时重新加载FetchedResults的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我认为我已经将问题范围缩小到了listview中的fetchresult.当fetchrequest(谓词)更改时,它不会重新获取.

edit: so far i think i've narrowed the problem done to the fetchresult in listview. when the fetchrequest(predicate) changes, it doesn't refetch.

我正在使用swiftUI和Core Data构建一个待办事项应用程序.在listView中,我有一个按钮,它将更改fetchrequest的谓词,但是我无法使其工作.

i'm building a todo app with swiftUI and Core Data. in the listView i have a button that'll change the predicate for the fetchrequest, but i can't get it to work.

listView中的代码

code in the listView

struct HomeListView: View {
    @Environment(\.managedObjectContext) var context
    @FetchRequest(fetchRequest: ItemEntity.loadItems()) var items: FetchedResults<ItemEntity>

    Text("someText")
        .onTapGesture {
            ItemEntity.predicateType.next() //next() is a method defined in core data entity class
        }

核心数据实体类中的

代码

code in the core data entity class

extension ItemEntity {
    static var sortType = sort.ascending
    static var predicateType = predicate.all

    static func loadItems() -> NSFetchRequest<ItemEntity> {
        var request: NSFetchRequest<ItemEntity> = ItemEntity.fetchRequest() as! NSFetchRequest<ItemEntity>

        var predicate: NSPredicate {
        switch predicateType {
        case .all:
            return NSPredicate(format: "type = %i", 0)
        case .imur:
            return NSPredicate(format: "type = %i", 0)
        case .unimur:
            return NSPredicate(format: "type = %i", 1)
        case .imunur:
            return NSPredicate(format: "type = %i", 2)
        case .unimunur:
            return NSPredicate(format: "type = %i", 3)
        case .entry:
            return NSPredicate(format: "type = %i", 4)
        }

        request.sortDescriptors = [sortDescriptor]
        request.predicate = predicate
        return request
    }

    enum predicate {
        case all
        case imur
        case unimur
        case imunur
        case unimunur
        case entry

        mutating func next() {
            switch self {
            case .all:
                self = .imur
            case .imur:
                self = .unimur
            case .unimur:
                self = .imunur
            case .imunur:
                self = .unimunur
            case .unimunur:
                self = .entry
            case .entry:
                self = .all
            }
        }
    }
}

这个想法是当用户点击列表视图上的按钮时,它调用next()方法并将ItemEntity类中的predicateType属性设置为另一个值,然后loadItems()中的predicate属性将更新fetchrequest,然后是listview将重新加载.

the idea is when user tap on the button on list view, it call the next() method and set predicateType property in ItemEntity class to another value, then the predicate property in loadItems() will update the fetchrequest, then the listview will reload.

我知道这种方法有问题,但是我不知道该如何解决.感谢您的帮助!

i know there is something wrong with this approach, but i can't figure out how to fix it. Thanks for helping!

推荐答案

您需要更改某些状态,以便视图重新呈现.

You need to change some state so that the view re-renders.

尝试添加 @State 变量,从按钮操作中将其更改并在视图中使用它:

Try adding a @State var, change it from the button action and use it in the view:

struct HomeListView: View {
    @Environment(\.managedObjectContext) var context
    @FetchRequest(fetchRequest: ItemEntity.loadItems()) var items: FetchedResults<ItemEntity>
    @State private var refresh: Bool = false  // add a state
  var body: some View {
    Text("someText")
        .onTapGesture {
            ItemEntity.predicateType.next() 
            refresh.toggle()     // change the state
        }
        .background(toggle ? Color.clear : Color.clear)  // use the state
    }
}

这篇关于在swiftUI中更改谓词时重新加载FetchedResults的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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