Reputation: 2998
Every time a row is selected the system decides to forward a random index to the next view.
Please look at the following video for clarification:
Below is the code:
struct TestView: View {
let columns = [
GridItem(.flexible())
]
@State var showDetail = false
var body: some View {
ScrollView {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(1...10, id: \.self) { index in
Text("\(index)")
.background(NavigationLink(destination: TestDetail(index: index), isActive: $showDetail) {
EmptyView()
}).onTapGesture {
showDetail = true
}
}
}
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
struct TestDetail: View {
var index: Int
var body: some View {
Text("\(index)")
}
}
Upvotes: 3
Views: 1588
Reputation: 258355
You activate all links at once (because all of them depends on one state). Instead we need to use different NavigationLink
constructor for such cases.
Here is fixed variant. Tested with Xcode 12.1 / iOS 14.1
struct TestView: View {
let columns = [
GridItem(.flexible())
]
@State var selectedItem: Int?
var body: some View {
ScrollView {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(1...10, id: \.self) { index in
Text("\(index)")
.background(NavigationLink(destination: TestDetail(index: index), tag: index, selection: $selectedItem) {
EmptyView()
}).onTapGesture {
selectedItem = index
}
}
}
}
}
}
Upvotes: 6
Reputation: 4245
You should use the standard NavigationLink features, which automatically convert it into a button - you don't really need the .background and .onTapGesture.
ForEach(1...10, id: \.self) { index in
NavigationLink(
destination: TestDetail(index: index),
label: {
Text("\(index)")
})
.accentColor(.primary)
}
Upvotes: 0