简体   繁体   中英

SwiftUI NavigationLink in LazyVGrid picking random index

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)")
    }
}

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
                        }
                }
            }
        }
    }
}

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)
                }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM