The sample app has a Core Data model of Garden entity that has a to-many relationship with Fruit entity. User is invited to pick fruits in the garden using a SwiftUI List in constant edit mode with a selection parameter set. The user selection will be reflected in the Core Data relationship. The issue is that when the user searches for something and then attempts to select a fruit, the search is reset. I'm assuming this is predefined behavior and wondering how to override it so the search persists i.e. the predicate that the user set via search is still active, and the list remains to be filtered.
struct FruitPicker: View {
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Fruit.name, ascending: true)],
animation: .default)
private var fruits: FetchedResults<Fruit>
@Binding var selection: Set<Fruit>
@State var searchText = ""
var body: some View {
List(fruits, id: \.self, selection: $selection) {
Text($0.name ?? "")
}
.searchable(text: query)
.environment(\.editMode, .constant(EditMode.active))
.navigationTitle("Garden")
}
var query: Binding<String> {
Binding {
searchText
} set: { newValue in
searchText = newValue
fruits.nsPredicate = newValue.isEmpty ? nil : NSPredicate(format: "name CONTAINS[cd] %@", newValue)
}
}
}
There is a post on the Apple developer portal that goes into a somewhat similar issue. The solution that is offered in the post is to pass in a predicate and sort descriptors from the parent into the view's initializer. I've tried that and it does not solve the issue.
init(selection: Binding<Set<Fruit>>, sortDescriptors: [NSSortDescriptor], predicate: NSPredicate?) {
_selection = selection
let entity = Fruit.entity()
_fruits = FetchRequest<Fruit>(entity: entity, sortDescriptors: sortDescriptors, predicate: predicate, animation: .default)
}
struct ContentView: View {
@ObservedObject var garden: Garden
var body: some View {
NavigationView {
NavigationLink("Pick Fruits in the Garden 🏡") {
FruitPicker(selection: $garden.fruits.setBinding(), sortDescriptors: [NSSortDescriptor(keyPath: \Fruit.name, ascending: true)], predicate: nil)
}
}
}
}
