0

In the code shown below I have a TrainingView with a Group to add data. This works perfectly. The console prints "saved" only and the view reloads with new data. I want to add the same data using a modal / sheet. I created the NewTrainingView that has the same action to add the data, but it does not work. The console prints saved and Error: nilError.

struct TrainingView: View {

    @State var showAdd = false
    @State var newTrainingName: String = ""

    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Training.name, ascending: true)]) var trainings: FetchedResults<Training>
    @Environment(\.managedObjectContext) var viewContext
    @Environment(\.presentationMode) var presentationMode

    var body: some View {

        NavigationView {
            VStack {
                Group {
                    VStack {
                        TextField("Name", text: $newTrainingName)
                            .padding()
                            .background(Color.white)
                            .cornerRadius(15)
                        Button(action: {
                            //THIS IS WORKING
                            let training = Training(context: self.viewContext)
                            training.name = self.newTrainingName
                            do {
                                print("saved")
                                try self.viewContext.save()
                            } catch let error {
                                print("Error: \(error)")
                            }
                        }) {
                            Text("Add")
                                .padding()
                        }
                    }
                    .padding()
                    .background(Color(#colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)))
                    .cornerRadius(15)
                }
                .padding()
                List {
                    ForEach(trainings, id: \.self) { training in
                        NavigationLink(destination: WorkoutView(training: training)) {
                            Text(training.name!)
                        }
                    }.onDelete(perform: deleteRow)
                }
            }
            .navigationBarTitle(Text("Trainings"))
            .navigationBarItems(
                trailing:
                    Button(action: {
                        self.showAdd.toggle()
                    }) {
                        Image(systemName: "plus")
                    }
                )
            .sheet(isPresented: $showAdd) {
                NewTrainingView()
            }
        }
    }

    func deleteRow(at indexSet: IndexSet) {
        for index in indexSet {
            let training = trainings[index]
            viewContext.delete(training)
            do {
                try viewContext.save()
            } catch let error {
                print("Error: \(error)")
            }
        }
    }
}

struct NewTrainingView: View {

    @Environment(\.presentationMode) var presentationMode
    @Environment(\.managedObjectContext) var viewContext

    @State var newTrainingText: String = ""

    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Gib deinem Plan einen Namen:")){
                    TextField("Name", text: $newTrainingText)
                }
                Button(action: {
                    if (self.newTrainingText != "") {
                        //THIS IS NOT WORKING
                        let training = Training(context: self.viewContext)
                        training.name = self.newTrainingText
                        do {
                            print("saved")
                            try self.viewContext.save()
                        } catch let error {
                            print("Error: \(error)")
                        }
                        self.presentationMode.wrappedValue.dismiss()
                    }
                }) {
                    Text("Hinzufügen")
                }
            }
            .navigationBarTitle(Text("Neuer Trainingsplan"))
            .navigationBarItems(leading: Button(action: {
                 self.presentationMode.wrappedValue.dismiss()
            }) {
                Text("Zurück")
            })
        }
    }
}
1
  • You will need to add an .onAppear to your first view to update the fetch request Commented Jun 15, 2020 at 8:41

1 Answer 1

2

Looks like you need to pass the managed object context to your NewTrainingView

.sheet(isPresented: $showAdd) {
    NewTrainingView()
        .environment(\.managedObjectContext, self.viewContext)    
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.