SwiftUI pass elements of an array as bindings to subview

Viewed 834

I try to make my first iOS app and I have the following issue and I cannot understand how to solve it. I have a tabbed MainPageView where I load all the data and then pass it through different views. When I add new Item in the Task view the new item appear in list, but I want to update also the TaskView when something happens like using contextmenu to mark a task as completed

The task struct:

struct Task: Identifiable, Hashable {
     var name: String = ""
     var status: Bool = false
     var notify: Bool = false

The MainPageView - here the tasks are under a Firebase observe so it should update automatically when changes are done in the database

struct MainPageView: View {
     @State private var tasks: [Task] = []
     ...
     var body: Some View{
          TabView{
             TaskPageView(tasklist: self.$tasks) ...

The TaskPageView

struct TaskPageView: View {
     @Binding var tasklist: [Task]
     ...
     var body: some View{
          NavigationView{
             List{
               ForEach(self.tasklist, id:\.self){ task in
                   NavigationLink(destination: TaskDetView(task: task)){
                        TaskView(name: task.name, done: task.status, notify: task.notify).contextMenu{
                           Button(action: { //mark task as done in FirebaseDB }) {
                               Image(systemName: "checkmark.circle").foregroundColor(Color.green)
                               Text("Mark as complete")
                    }
                   }
               }
          }

And TaskView

struct TaskView: View {
var name: String
var done: Bool
var notify: Bool

var body: some View {
    ZStack{
        HStack{
            Text(name)
            Spacer()
            if notify{
                Image(systemName: "bell")
            }
            Text(done ? "Done" : "Not completed").font(.system(size: 10))
        }
    }
}

}

What I want to achieve is when the user clicks Mark as complete button in context menu to force the change of the text in TaskView in the TaskPageView list. I have tried to make another class like Tasks which was ObservableObject where a list of tasks was @Published, in MainPageView make the tasklist as @ObservedObject and use in ForEach .indices and pass the task as tasklist[idx] with still no success.

Thanks for your time!

1 Answers

For future reference, as you and Asperi stated in the comments, you can make an ObservableObject / a StateObject tasks, put array of tasks in it as a Published variable, populate tasks inside main view and pass the tasks to the subviews as observable objects(not StateObject). You don't need to make the task environmentObject in subviews even though it would work like that too.

Related