SwiftUI View and @FetchRequest predicate with variable that can change

后端 未结 5 1398
予麋鹿
予麋鹿 2020-12-02 14:06

I have a view showing messages in a team that are filtered using @Fetchrequest with a fixed predicate \'Developers\'.

struct ChatView: View {

@FetchRequest(         


        
5条回答
  •  旧时难觅i
    2020-12-02 14:08

    May be a more general solution for dynamically filtering @FetchRequest.

    1、Create custom DynamicFetchView

    import CoreData
    import SwiftUI
    
    struct DynamicFetchView: View {
        let fetchRequest: FetchRequest
        let content: (FetchedResults) -> Content
    
        var body: some View {
            self.content(fetchRequest.wrappedValue)
        }
    
        init(predicate: NSPredicate?, sortDescriptors: [NSSortDescriptor], @ViewBuilder content: @escaping (FetchedResults) -> Content) {
            fetchRequest = FetchRequest(entity: T.entity(), sortDescriptors: sortDescriptors, predicate: predicate)
            self.content = content
        }
    
        init(fetchRequest: NSFetchRequest, @ViewBuilder content: @escaping (FetchedResults) -> Content) {
            self.fetchRequest = FetchRequest(fetchRequest: fetchRequest)
            self.content = content
        }
    }
    
    

    2、how to use

    //our managed object
    public class Event: NSManagedObject{
        @NSManaged public var status: String?
        @NSManaged public var createTime: Date?
        ... ...
    }
    
    // some view
    
    struct DynamicFetchViewExample: View {
        @State var status: String = "undo"
    
        var body: some View {
            VStack {
                Button(action: {
                    self.status = self.status == "done" ? "undo" : "done"
                }) {
                    Text("change status")
                        .padding()
                }
    
                // use like this
                DynamicFetchView(predicate: NSPredicate(format: "status==%@", self.status as String), sortDescriptors: [NSSortDescriptor(key: "createTime", ascending: true)]) { (events: FetchedResults) in
                    // use you wanted result
                    // ...
                    HStack {
                        Text(String(events.count))
                        ForEach(events, id: \.self) { event in
                            Text(event.name ?? "")
                        }
                    }
                }
    
                // or this
                DynamicFetchView(fetchRequest: createRequest(status: self.status)) { (events: FetchedResults) in
                    // use you wanted result
                    // ...
                    HStack {
                        Text(String(events.count))
                        ForEach(events, id: \.self) { event in
                            Text(event.name ?? "")
                        }
                    }
                }
            }
        }
    
        func createRequest(status: String) -> NSFetchRequest {
            let request = Event.fetchRequest() as! NSFetchRequest
            request.predicate = NSPredicate(format: "status==%@", status as String)
            // warning: FetchRequest must have a sort descriptor
            request.sortDescriptors = [NSSortDescriptor(key: "createTime", ascending: true)]
            return request
        }
    }
    

    In this way, you can dynamic change your NSPredicate or NSSortDescriptor.

提交回复
热议问题