So I have this code:
struct SelectorView: View {
let levelamt: Int = 50
var next: Int = 20
let columns: [GridItem] = [GridItem(), GridItem(), GridItem()]
var body: some View {
NavigationStack {
ZStack {
Color(red: 0, green: 0, blue: 0).ignoresSafeArea()
LazyVGrid(columns: columns) {
ForEach(1..<next, idx: \.self) { x in
NavigationLink(destination: GameView(level: self.x), label: {
ZStack {
Image("Fragment")
.resizable()
.frame(width: 125, height: 125)
.scaledToFit()
Text(String(x))
.font(.system(size: 50, design: .monospaced))
.fontWeight(.bold)
.foregroundColor(Color.white)
}
})
}
}
}
}
}
}
}
It's saying that x cannot be passed into GameView's Binding Int level. Can someone please tell me how this works and how to fix it?
Here's the GameView code (it doesn't have anything because I haven't gotten to it yet):
struct GameView: View {
@Binding var level: Int
var body: some View {
Text("hello world")
}
}
I'm using the legacy version of NavigationLink because I personally feel that it's more convenient to code. When I finish the app, I'll look into it to optimize it. I've also seen the other similar posts but the solutions on those don't work for some reason, maybe because the ForEach is a range and not an array.
...to pass a ForEach variable into a Binding through a NavigationLink
,
try this approach using a separate struct GameItem
to hold your game levels, and
using binding ($
) in the ForEach()
loop.
struct GameItem: Identifiable { // <--- here
let id = UUID()
var level: Int
}
struct SelectorView: View {
let levelamt: Int = 50
var next: Int = 20
let columns: [GridItem] = [GridItem(), GridItem(), GridItem()]
// for testing
@State private var items = [GameItem(level: 0),GameItem(level: 1),GameItem(level: 2)]
var body: some View {
NavigationStack {
ZStack {
Color(red: 0, green: 0, blue: 0).ignoresSafeArea()
LazyVGrid(columns: columns) {
ForEach($items) { $item in // <--- here $
NavigationLink(destination: GameView(level: $item.level), label: { // <--- here
ZStack {
Image("Fragment")
.resizable()
.frame(width: 125, height: 125)
.scaledToFit()
Text(String(item.level)) // <--- here
.font(.system(size: 50, design: .monospaced))
.fontWeight(.bold)
.foregroundColor(Color.white)
}
})
}
}
}
}
}
}
struct GameView: View {
@Binding var level: Int
var body: some View {
Text("GameView \(level)")
Button("Increment level") { // <--- for testing
level += 1
}
}
}
struct ContentView: View {
var body: some View {
SelectorView()
}
}