ForEach Loop and Navigation Link

I get 3 errors:

Referencing initializer 'init(_:content:)' on 'ForEach' requires that 'NavigationLink<VStack<TupleView<(some View, Text)>>, itemDetail>' conform to 'TableRowContent'

And

Static method 'buildBlock' requires that 'NavigationLink<VStack<TupleView<(some View, Text)>>, itemDetail>' conform to 'TableRowContent'

Both errors are at the ForEach Loop

And the third one is at the VStack

Contextual closure type '() -> TupleView<(some View, Text)>' expects 0 arguments, but 1 was used in closure body

(Im new to Swift/SwiftUI)

struct ContentView: View {

private let gridItems = [GridItem(.flexible()), GridItem(.flexible())]

@EnvironmentObject private var vm: LocationsViewModel

    

var body: some View {

NavigationView {
    ScrollView(showsIndicators: false) {
        LazyVGrid (columns: gridItems, spacing: 15) {
           ForEach(vm.locations) {
              NavigationLink (destination: itemDetail()) {
                    VStack {
                        Image($0.img)
                                .resizable()
                                .scaledToFit()
                                .cornerRadius(15)
                                .padding(3.0)
                        Text($0.name)
                   }
               }
            }.navigationTitle("Title")
        }
    }
}
}
}


Thanks for any help

Accepted Answer

I replicated to show the pattern

  • ItemDetail (note that name should start with Uppercase)
  • Location and make it hashable
  • LocationsViewModel as ObservableObject

You misused environmentObject.

struct ItemDetail: View {
    var body: some View {
        Text("itemDetail")
    }
}

struct Location: Hashable {
    var img: String      // You will have a real image, not just a String
    var name : String
}
class LocationsViewModel : ObservableObject {
    @EnvironmentObject var vm: LocationsViewModel
    var locations : [Location] = [Location(img: "img", name: "name")]
}
struct ContentView: View {
    
    private let gridItems = [GridItem(.flexible()), GridItem(.flexible())]
    @StateObject var vm = LocationsViewModel()     // <<-- State
//    @EnvironmentObject var vm: LocationsViewModel
    
    var body: some View {
        
        NavigationView {
            ScrollView(showsIndicators: false) {
                LazyVGrid (columns: gridItems, spacing: 15) {
                    ForEach(vm.locations, id: \.self) { location in       // declare id and location in
                        NavigationLink (destination: ItemDetail()) {
                            VStack {
                                Image(location.img)      // Don't use $0, but explicit parameter location 
                                    .resizable()
                                    .scaledToFit()
                                    .cornerRadius(15)
                                    .padding(3.0)
                                Text(location.name)
                            }
                        }
                    }.navigationTitle("Title")
                }
            }
        }
    }
}

To learn more : https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data-between-views

ForEach Loop and Navigation Link
 
 
Q