0
votes

My full project is here https://github.com/m3rtkoksal/TaskManager

I have made SelectedTask an environment object as below

let context = persistentContainer.viewContext
    let contentView = ContentView()
                                    .environmentObject(observer())
                                    .environmentObject(SelectedTask())
                                    .environment(\.managedObjectContext,context)

In my TaskElement model I have created another class called SelectedTask as below

class SelectedTask: ObservableObject {
@Published var item = [TaskElement]()

func appendNewTask(task: TaskElement) {
    objectWillChange.send()
    item.append(TaskElement(title: task.title, dateFrom: task.dateFrom , dateTo: task.dateTo , text: task.text))
   }
 }

I am trying to fetch an item inside the scroll view and get its data to be able to modify it in the NewTaskView as below

struct ScrollViewTask: View {
@ObservedObject private var obser = observer()
@EnvironmentObject var selectedTask : SelectedTask
@State var shown: Bool = false
var body: some View {
    
    ScrollView(.vertical) {
        VStack {
            ForEach(self.obser.tasks) { task in
                TaskElementView(task:task)
                    .onTapGesture {
                        self.selectedTask.objectWillChange.send()
                        self.selectedTask.appendNewTask(task: task) //THREAD 1 ERROR
                        print(task)
                        self.shown.toggle()
                    }
            }
        }
    }
    .onAppear {
        self.obser.fetchData()
    }
    .fullScreenCover(isPresented: $shown, content: {
        NewTaskView(isShown: $shown)
            .environmentObject(selectedTask)
      })
    }
   }

But when I tap one of the items in scrollview I am getting a Thread 1 error @self.selectedTask.appendNewTask(task: task)

Thread 1: Fatal error: No ObservableObject of type SelectedTask found. A View.environmentObject(_:) for SelectedTask may be missing as an ancestor of this view.

If I change as ScrollViewTask().environmentObject(self.obser)

then this happensenter image description here

This is how my TaskFrameView is called

import SwiftUI

struct TaskListView: View {
@State private(set) var data = ""
@State var isSettings: Bool = false
@State var isSaved: Bool = false
@State var shown: Bool = false
@State var selectedTask = TaskElement(title: "", dateFrom: "", dateTo: "", text: "")
var body: some View {
    NavigationView {
        ZStack {
            Color(#colorLiteral(red: 0.9333333333, green: 0.9450980392, blue: 0.9882352941, alpha: 1)).edgesIgnoringSafeArea(.all)
            VStack {
                TopBar()
                HStack {...}
                CustomSegmentedView()
                ZStack {
                    TaskFrameView() // scrollview inside
                    VStack {
                        Spacer()
                        HStack {...}
                    }
                    NavigationLink(
                        destination: NewTaskView(isShown: $shown).environmentObject(selectedTask),
                        isActive: $shown,
                        label: {
                            Text("")
                        })
                }
            }
        }
        .navigationBarHidden(true)
        Spacer()
    }
    .navigationBarHidden(true)
     }
    }
2
@Asperi do you have any idea? - Mert Köksal
How is your ScrollViewTask called? Is it created directly in the ContentView? Or is it called with a NavigationLink, sheet etc? - pawello2222
@pawello2222 I have added where I call - Mert Köksal
in TaskFrameView - Mert Köksal
But isn't your goal to have only one selectedTask in your App? If so why do you create @State var selectedTask = TaskElement(title: "", dateFrom: "", dateTo: "", text: "") in TaskListView? - pawello2222

2 Answers

1
votes

It looks like the selectedTask is not injected to the TaskListView.

Find the place where you call TaskListView() and inject the selectedTask as an EnvironmentObject.

In ContentView:

struct ContentView: View {
    @EnvironmentObject var selectedTask : SelectedTask
    ...
TaskListView().environmentObject(selectedTask)

Also don't create new instances of selectedTask like:

@State var selectedTask = TaskElement(title: "", dateFrom: "", dateTo: "", text: "")

Get the already created instance from the environment instead:

@EnvironmentObject var selectedTask: SelectedTask
0
votes

call scroll view by sending the observer object as environment object modifier ScrollViewTask().environmentObject(self. observer)