2

In my IssueListView I have a structure:

struct MyResults: Codable {
var id: Int
var problem: String
var recordDate: String
var isDone: Bool
var finishedDate: String?
var imagePath: String?

}

and a State which is array of the above structure:

@State private var myresults = [MyResults]()

and every thing work fine as I use this array to receive data from API onAppear() and show it as list in the same view.

The problem start when I decide to make a new view (AddTaskView) to add tasks.

the code adding the new task using API successfully, but I have to dismiss the view after that and my list did not updated as the onApear start only once and I don't know how to update the list here inside AddTaskView or to make IssueListView load the data again

1 Answer 1

4

Approach 1: State and Binding

If myresults is a @State wrapped variable, you should have a @Binding variable in AddTaskView:

struct IssueListView: View {
  @State private var myresults = [MyResults]()

  var body: some View {
    yourContentHere
      .onAppear {
        // Load the data from API here.
      }
      .sheet {
        AddTaskView(myresults: $myresults)
      }
  }
}

struct AddTaskView: View {
  @Binding var myresults: [MyResults]

  var body: some View {
    // ...
  }
}

Any changes written to myresults within AddTaskView will reflect and update on IssueListView so long as it is passed in AddTaskView's initializer.

Approach 2: ViewModel

Another great solution is to use MVVM architecture in your app. Create a View Model for your Results list, and have myresults as a @Published wrapped property:

class ResultsViewModel: ObservableObject {
  @Published var myresults = [MyResults]()

  // Add API calls here as methods.
}

Then, initialize ResultsViewModel in IssueListView and pass it to AddTaskView:

struct IssueListView: View {
  @StateObject var viewModel = ResultsViewModel()

  var body: some View {
    yourContentHere
      .onAppear {
        viewModel.someAPICall()
      }
      .sheet {
        AddTaskView(viewModel: viewModel)
      }
  }
}

struct AddTaskView: View {
  @ObservedObject var viewModel: ResultsViewModel

  var body: some View {
    // ...
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, In method #1, I get error in AddTasskView: Missing argument for parameter 'myresults' in call. Insert ', myresults: <#Binding<[MyResults]>#>'
I tried many ways to fix it, 1- first by create mock data in another file, 2- by pass constant variable 3- by pass static variable. the 2, 3 remove the error but the list docent updated
Since myresults is a @Binding variable in AddTaskView, and it doesn't have an initial stored value, Swift will ask for a Binding<> value when initializing AddTaskView. So, make sure to call AddTaskView(myresults: $myresults) in your view. The $ passes myresults as Binding<[MyResults]>.
I removed the AddTaskView preview part so I don't need to initial or pass parameter. and it's work! Thanks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.