I am trying to make a list of eatery locations each of which are displayed in an EateryRow which is able to be clicked to move to the EateryDetail page, however with the implementation of this code I get an error which I believe is related to the syntax of the NavigationLink argument.
Also: I found this question which seems to have the same problem as me but it remains unanswered.
import SwiftUI
struct EateryList: View {
@Binding var eateries: [Eatery]
var body: some View {
NavigationView {
VStack {
List {
ForEach(eateries) {
NavigationLink(destination: EateryDetail(eatery: $eateries[identifiedBy: $0])) { //error here
EateryRow(eatery: $eateries[identifiedBy: $0])
}
}
.onMove {
eateries.move(fromOffsets: $0, toOffset: $1)
EateriesApp.save()
}.onDelete {
eateries.remove(atOffsets: $0)
EateriesApp.save()
}
}
.navigationTitle("Favourite Eateries")
.navigationBarItems(leading: EditButton(), trailing: Button( action: add)
{
Image(systemName: "plus")
}
)
.listStyle(InsetGroupedListStyle())
}
}
}
func add() {
eateries.append(Eatery(name: "Eatery", location: "Insert location here", notes: "Insert notes here", reviews: ["Insert reviews here"], url: "https://i.imgur.com/y3MMnba.png"))
EateriesApp.save()
}
}
I get this error on the line with the NavigationLink:
Unnamed argument #2 must precede argument 'destination'
For further clarity this is how I've used the "eatery" variable in the EateryDetail and EatertyRow views:
struct EateryDetail: View {
@Binding var eatery: Eatery
struct EateryRow: View {
@Binding var eatery: Eatery
And here is my code for Eatery which is defined in a file called eateries.swift:
import Foundation
struct Eatery: Codable, Identifiable {
var id = UUID()
var name: String
var location: String
var notes: String
var reviews: [String] = []
var url: String = ""
}
In eateriesApp.swift this is also defined:
import SwiftUI
@main
struct EateriesApp: App {
@State var model: [Eatery] = EateriesApp.model
static var model: [Eatery] = {
guard let data = try? Data(contentsOf: EateriesApp.fileURL),
let model = try? JSONDecoder().decode([Eatery].self, from: data) else {
return [elCaminoCantina, theFineDine, nightBites, theRiverRodeo, theCozyKitchen, theElegantEatery]
}
return model
}()
static var modelBinding: Binding<[Eatery]>?
var body: some Scene {
EateriesApp.modelBinding = $model
return WindowGroup {
ContentView(eateries: $model)
}
}
You should need to use .indices
in ForEach(eateries)
.
Like this
ForEach(eateries.indices) { index in
NavigationLink(destination: EateryDetail(eatery: $eateries[index])) { //error here
EateryRow(eatery: $eateries[index])
}
}
The problem is you are using a shorthand variable ($0). When you used $0 inside the NavigationLink
then $0 is considered for NavigationLink not ForEach
. so now both $0 are in conflict in your case.
You can check with the below code. In below code now not produce any error because now there is no use $0 inside the NavigationLink
ForEach(eateries) {
Text($0.name)
NavigationLink(destination: EateryDetail(eatery: $eateries[identifiedBy: $0])) {
Text("$0.name")
}
}
Another solution is to use one variable and store your $0 data like this.
ForEach(eateries) {
let eaterie = $0 //<--- Here
NavigationLink(destination: EateryDetail(eatery: $eateries[identifiedBy: eaterie])) { //<--- Here
EateryRow(eatery: $eateries[identifiedBy: eaterie]) //<--- Here
}
}