我可以在 Picker() 中将 @FetchRequest 与 @State var 一起使用吗?
Can I use @FetchRequest with a @State var in a Picker()?
我不知道如何将 @State var 绑定到选择器以便更新 @FetchRequest。
此代码可以编译,但更改选取器选择对 fetchRequest 没有任何作用,因为它没有调用 init.其他各种变体大多都失败了。
我该如何完成?
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)
)
}
有几种方法可以解决这个问题,这是我的。不确定 Skill
的预期用途,但我认为您可以弄清楚如何让它为您工作。
我会让设备成为 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"
}
}
}
延长 Item
extension Item {
var unwrappedApparatus: Apparatus {
Apparatus(rawValue: Int(apparatus)) ?? Apparatus.vault
}
var unwrappedName: String {
name ?? "Unknown"
}
}
在 ContentView
中设置您的 @State
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
}
}
}
现在根据selectedApparatus
把你要改的View
打出来自己的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)
}
}
}
我不知道如何将 @State var 绑定到选择器以便更新 @FetchRequest。
此代码可以编译,但更改选取器选择对 fetchRequest 没有任何作用,因为它没有调用 init.其他各种变体大多都失败了。
我该如何完成?
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)
)
}
有几种方法可以解决这个问题,这是我的。不确定 Skill
的预期用途,但我认为您可以弄清楚如何让它为您工作。
我会让设备成为 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"
}
}
}
延长 Item
extension Item {
var unwrappedApparatus: Apparatus {
Apparatus(rawValue: Int(apparatus)) ?? Apparatus.vault
}
var unwrappedName: String {
name ?? "Unknown"
}
}
在 ContentView
@State
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
}
}
}
现在根据selectedApparatus
把你要改的View
打出来自己的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)
}
}
}