Reputation: 707
I cannot figure out how to tie in the @State var to a picker so that @FetchRequest will update.
This code compiles, but changing the picker selection does nothing to fetchRequest, because it's not calling the init. All kinds of other variants have failed mostly.
How do I accomplish this?
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@State private var selectedSkill: Skill? = nil
@State private var pickerSelection: Int
@FetchRequest var skills: FetchedResults<Skill>
init(pickerSelection: Int) {
self._pickerSelection = State(initialValue: pickerSelection)
self._skills = FetchRequest(
entity: Skill.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Skill.value, ascending: true)],
predicate: NSPredicate(format: "apparatus == %d", pickerSelection)
)
}
Upvotes: 1
Views: 396
Reputation: 684
There are a few ways to go about this here is mine. Not sure of your intended use of Skill
but I think you can figure out how to make it work for you.
I would make apparatus an enum
enum Apparatus: Int, CaseIterable, CustomStringConvertible, Identifiable {
case vault, unevenBars, balanceBeam, all
var id: String { self.description }
var description: String {
switch self {
case .vault: return "Vault"
case .unevenBars: return "Uneven Bars"
case .balanceBeam: return "Balance Beam"
case .all: return "All"
}
}
}
extend on Item
extension Item {
var unwrappedApparatus: Apparatus {
Apparatus(rawValue: Int(apparatus)) ?? Apparatus.vault
}
var unwrappedName: String {
name ?? "Unknown"
}
}
Set your @State
in ContentView
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@State var selectedApparatus = Apparatus.vault
var body: some View {
List {
Picker("Apparatus", selection: $selectedApparatus) {
Text("Vault").tag(Apparatus.vault)
Text("Uneven Bars").tag(Apparatus.unevenBars)
Text("Balance Beam").tag(Apparatus.balanceBeam)
Text("All").tag(Apparatus.all)
}
Text(selectedApparatus.description)
ItemsView(selectedApparatus: $selectedApparatus) // <-- View changing on selectedApparatus
}
}
}
Now break out the View
you want to change based on the selectedApparatus
to its own View
struct ItemsView: View {
@FetchRequest private var items: FetchedResults<Item>
init(selectedApparatus: Binding<Apparatus>) {
self._items = FetchRequest(entity: Item.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Item.name, ascending: true)],
predicate: selectedApparatus.wrappedValue == .all ? nil : NSPredicate(format: "apparatus == %d", selectedApparatus.wrappedValue.rawValue))
}
var body: some View {
ForEach(items) { item in
Text(item.unwrappedName)
}
}
}
Upvotes: 1