I am trying to transfer the same API data from the first view and display the rest of the details in the second view
The problem is that the same first data is displayed in all index
struct model: Codable, Identifiable {
let id = UUID()
var details : String
var title : String
}
and fetch data here
class Api : ObservableObject{
@Published var models : [model] = []
func getData (url : String) {
guard let url = URL(string: url) else { return }
var request = URLRequest(url: url)
request.setValue("Bearer \(APIgetURL.Token)", forHTTPHeaderField: "Authorization")
URLSession.shared.dataTask(with: request) { data, responce, err in
guard let data = data else { return }
do {
let dataModel = try JSONDecoder().decode([model].self, from: data)
DispatchQueue.main.async {
self.models = dataModel
}
} catch {
print("error: ", error)
}
}
.resume()
}
}
Here I present the data in the first view
ForEach(modelname.models) { item in
NavigationLink(destination: DetilesTap1(modelname: modelname)) {
Rectangle()
.cornerRadius(15)
.frame(width: .infinity, height: 40)
.foregroundColor(.white)
.shadow(color: .black.opacity(0.3), radius: 20)
.padding(.trailing).padding(.leading)
.overlay(
HStack {
Text(item.title)
.padding(.trailing,30).padding(.leading,30)
Spacer()
Image(systemName: "arrow.down.doc.fill")
.padding(.trailing,30).padding(.leading,30)
}
)
}
}
Here is the second view
ForEach(modelname.models) { item in
VStack(alignment: .center) {
VStack(spacing: 10) {
Text(item.title)
Text(item.details)
Spacer()
}
}
}
I tried to put the id and the same problem
Despite all the explanations and methods available, they all have the same problem
CodePudding user response:
You haven't posted a Minimal Reproducible Example (MRE), so this is an educated guess. Assuming that
@StateObject var modelname = Api()
Then your first view should be:
// keep you naming consistent. item is really of type Model, so call it model.
ForEach(modelname.models) { model in
// Pass just the model data you want to display, not everything.
NavigationLink(destination: DetilesTap1(model: model)) {
...
}
in your second view:
struct DetailView: View {
let model: Model
var body: some View {
// the two VStack were redundant.
VStack(alignment: .center, spacing: 10) {
Text(model.title)
Text(model.details)
Spacer()
}
}
}
You just need to pass the data you want to display, not everything all over again. That is the point of the ForEach
. It allows you to take each element and deal with it individually no indexes needed. Please study Apple’s SwiftUI Tutorials & Stanford’s CS193P. You need a better base of knowledge on how SwiftUI works.