Extending what has already been suggested, you can modify the predicate of the wrappedValue to dynamically trigger an update to a SwiftUI list. In the example below, toggling the isFiltered @State causes an update of the List and it reloads the FetchedResults with the filtered or unfiltered predicate.
@FetchRequest private var items: FetchedResults<Item>
@State var isFiltered = false
let filteredPredicate: NSPredicate
let unfilteredPredicate: NSPredicate
init(element: Element) {
self.element = element
filteredPredicate = NSPredicate(format: "element == %@ && score > 0.85", element)
unfilteredPredicate = NSPredicate(format: "element == %@", element)
self._items = FetchRequest<Item>(entity: Item.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Item.name, ascending: true),
predicate: unfilteredPredicate,
animation: .default)
}
var listItems: FetchedResults<Moment> {
get {
_moments.wrappedValue.nsPredicate = isFiltered ? filteredPredicate : unfilteredPredicate
return moments
}
}
var body: some View {
List {
ForEach(Array(listItems.enumerated()), id: \.element) { index, item in
Text(item.name)
.toolbar {
ToolbarItem {
Button {
withAnimation {
isFiltered.toggle()
}
} label: {
Label("Filter Items", systemImage: isFiltered ? "star.circle.fill" : "star.circle")
}
}
}
}
}
}