Search code examples
swiftuicore-datacombine

Bind @State picker value to a NSPredicate in SwiftUI


I have a view with a segmented picker. This view displays results of a FetchRequest. I'd like the predicate linked to this request to change when the picker value change.

Here's what I tried but I can't get around the fact that @FetchRequest cannot use a @State var since they're not both created at init().

@FetchRequest(sortDescriptors: [
    SortDescriptor(\.date, order: .reverse)
], predicate: NSPredicate(format: "date >= %@", selectedTimeFrame.getDate() as NSDate)) var sessions: FetchedResults<Session>

@State private var selectedTimeFrame = TimeFrame.thisWeek

This give me this error which I understand but I can't think of another way to make this work:

Cannot use instance member 'selectedTimeFrame' within property initializer; property initializers run before 'self' is available


Solution

  • You can handle this by setting an initial predicate for your FetchRequest, e.g.

    @FetchRequest(sortDescriptors: [
        SortDescriptor(\.date, order: .reverse)
    ], predicate: NSPredicate(format: "date >= %@", TimeFrame.thisWeek as NSDate)) var sessions: FetchedResults<Session>
    
    @State private var selectedTimeFrame = TimeFrame.thisWeek
    

    and then in your view, update the predicate when the State changes, e.g.

    .onChange(of: selectedTimeFrame) { selectedTimeFrame
        sessions.nsPreciate = NSPredicate(format: "date >= %@", selectedTimeFrame.getDate() as NSDate)) 
    }