Why I am not success to pass data from one view to another view for many data in SwiftUI?

I ask this question before, it was answered but it is not work for many data, like when I click the any list items, all details pass name of "david", I want to pass data of user which I clicked, where I missed here?

struct ImageModel: Identifiable, Hashable {
  var id = UUID().uuidString
  var name: String
 
}

var datas = [
   
  ImageModel(name: "davis"),
  ImageModel(name: "carry"),
  ImageModel(name: "maria"),

]
struct ImageRowView: View {
  var data: ImageModel
  var body: some View {
  
        NavigationLink(destination: ImageDetailsView(data: ImageModel)){
           
          HStack{}
}}}
struct ImageDetailsView: View {
  
  var body: some View {
     
   ImageDetails(data:  ImageModel(name: "davis"))
  }
}

struct ImageDetailsView_Previews: PreviewProvider {
  static var previews: some View {
     
    ImageDetailsView()
     
  }
}


struct ImageDetails : View {
  
  var data: ImageModel

  var body: some View{

  VStack{
            Text(data.name)
          
          }
}
Answered by szymczyk in 705531022

The reason the image detail view always shows davis is because your image details view always uses the davis image model.

struct ImageDetailsView: View {
  
  var body: some View {
     
   ImageDetails(data:  ImageModel(name: "davis"))
  }
}

You need to add a property to the image details view that stores the image model to display.

@Binding var imageModel: ImageModel

Pass the property to ImageDetails.

ImageDetails(data: $imageModel)

I don't see any list code, but you have to create a @State property in the view that has the list to store the selected list item.

@State private var selectedImage: ImageModel? = nil

Your list code should contain a navigation link to the details view.

NavigationLink(destination: ImageDetailsView(imageModel: $selectedImage))

Now the details view would show the selected image. But your code has a problem. In both ImageRowView and ImageDetails, you have the following property:

var data: ImageModel

SwiftUI views do not live long. When a change occurs to a view, SwiftUI creates a brand new view. When SwiftUI creates a new view, you will lose the contents of the data variable. In ImageRowView, you should declare a @State property like the selectedImage property I declared earlier. When you use @State, SwiftUI will keep the property when it creates a new view. In ImageDetails you should declare a @Binding property, like the imageModel binding I declared earlier, so it will show the selected image model.

I can't guarantee that everything will work now, but it should get you towards a solution. If you need a working example, the GitHub project at the following URL provides an example of handling list selection and working with @State and @Binding:

https://github.com/SwiftDevJournal/WikiDemo

Accepted Answer

The reason the image detail view always shows davis is because your image details view always uses the davis image model.

struct ImageDetailsView: View {
  
  var body: some View {
     
   ImageDetails(data:  ImageModel(name: "davis"))
  }
}

You need to add a property to the image details view that stores the image model to display.

@Binding var imageModel: ImageModel

Pass the property to ImageDetails.

ImageDetails(data: $imageModel)

I don't see any list code, but you have to create a @State property in the view that has the list to store the selected list item.

@State private var selectedImage: ImageModel? = nil

Your list code should contain a navigation link to the details view.

NavigationLink(destination: ImageDetailsView(imageModel: $selectedImage))

Now the details view would show the selected image. But your code has a problem. In both ImageRowView and ImageDetails, you have the following property:

var data: ImageModel

SwiftUI views do not live long. When a change occurs to a view, SwiftUI creates a brand new view. When SwiftUI creates a new view, you will lose the contents of the data variable. In ImageRowView, you should declare a @State property like the selectedImage property I declared earlier. When you use @State, SwiftUI will keep the property when it creates a new view. In ImageDetails you should declare a @Binding property, like the imageModel binding I declared earlier, so it will show the selected image model.

I can't guarantee that everything will work now, but it should get you towards a solution. If you need a working example, the GitHub project at the following URL provides an example of handling list selection and working with @State and @Binding:

https://github.com/SwiftDevJournal/WikiDemo

Why I am not success to pass data from one view to another view for many data in SwiftUI?
 
 
Q