.onTapGesture Get Scrollview Item Data

135 views Asked by At

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

There are 2 answers

2
pawello2222 On BEST ANSWER

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
1
Admiral On

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