我正在创建一个 swiftUI 应用程序(称为 Interval),它使用 CoreData 以一对多关系存储锻炼及其步骤。每个锻炼都有很多步骤。
ContentView -> DetailView -> EditView(作为工作表)
ContentView 显示所有锻炼的列表。点击列表中的锻炼会打开 DetailView,其中会显示所选锻炼中所有步骤的列表。
在 DetailView 中,点击工具栏中的按钮会打开一个名为 EditView 的工作表,其中列出了所选锻炼中的所有步骤,并允许用户添加、删除或重新排序步骤。
为了确保列表功能适用于 CoreData,我在 EditView 中使用 fetchRequest 来获取所选锻炼的所有步骤。到目前为止,我无法使用任何其他方法维护列表功能(.onDelete、.onMove)。
当我打开EditView时,弹出如下警告:
“环境中的上下文未连接到持久存储协调器:
如何删除警告,并确保我的上下文连接到持久存储协调器?
我假设 EditView 工作表会继承环境并自动连接到持久存储容器。似乎并非如此。
import SwiftUI
@main
struct IntervalApp: App {
@StateObject var dataController = DataController()
var body: some Scene {
WindowGroup {
NavigationStack {
ContentView()
.environment(\.managedObjectContext, dataController.container.viewContext)
}
}
}
}
import Foundation
import CoreData
import SwiftUI
class DataController: ObservableObject {
let container = NSPersistentContainer(name: "Interval")
init() {
container.loadPersistentStores { description, error in
if let error = error {
print("CoreData failed to load: \(error.localizedDescription)")
}
}
}
}
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(fetchRequest: Workout.all()) private var workouts
var body: some View {
List {
ForEach(workouts) { workout in
NavigationLink {
DetailView(workout: workout)
} label: {
Text(workout.title)
}
}
}
.navigationTitle("Workouts")
}
}
import SwiftUI
struct DetailView: View {
@Environment(\.dismiss) var dismiss
@Environment(\.managedObjectContext) var moc
@ObservedObject var workout: Workout
@State private var showSheet: Bool = false
var body: some View {
List {
// list steps
}
.navigationBarTitle(workout.title)
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
Button {
showSheet.toggle()
} label: {
Label("Edit", systemImage: "square.and.pencil")
}
}
}
.sheet(isPresented: $showSheet) {
NavigationStack {
EditView(workout: workout)
//.environment(\.managedObjectContext, moc) -> this did not work
}
}
}
}
import SwiftUI
import CoreData
struct EditView: View {
@Environment(\.dismiss) var dismiss
@Environment(\.managedObjectContext) var moc
@ObservedObject private var workout: Workout
@FetchRequest private var steps: FetchedResults<Step>
init(workout: Workout) {
self.workout = workout
_steps = FetchRequest(
entity: Step.entity(),
sortDescriptors: [ NSSortDescriptor(keyPath: \Step.index, ascending: true) ],
predicate: NSPredicate(format: "workout == %@", workout)
)
}
var body: some View {
List {
Section {
ForEach(steps) { step in
// list steps
}
//.onDelete()
//.onMove()
} header: {
Text("Steps")
}
}
.navigationTitle("Edit workout")
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button {
// save
dismiss()
} label: {
Text("Save")
}
}
}
}
}
我试过将环境从 DetailView 传递到 EditView 工作表,如下所示:
.sheet(isPresented: $showSheet) {
NavigationStack {
EditView(workout: workout)
.environment(\.managedObjectContext, moc) // Adding this did not work
}
}
...但是没有用。