我可以在 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)
    }
  }
}