SwiftUI NavigationLink в LazyVGrid выбирает случайный индекс

#ios #swift #swiftui

#iOS #swift #swiftui

Вопрос:

Каждый раз, когда выбирается строка, система решает перенаправить случайный индекс в следующее представление.

Пожалуйста, посмотрите следующее видео для уточнения: введите описание изображения здесь

Ниже приведен код:

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

Ответ №1:

Вы активируете все ссылки одновременно (потому что все они зависят от одного состояния). Вместо этого нам нужно использовать другой NavigationLink конструктор для таких случаев.

Вот исправленный вариант. Протестировано с 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
                        }
                }
            }
        }
    }
}
  

Ответ №2:

Вы должны использовать стандартные функции NavigationLink, которые автоматически преобразуют его в кнопку — на самом деле вам не нужны .background и .onTapGesture .

                 ForEach(1...10, id: .self) { index in
                    NavigationLink(
                        destination: TestDetail(index: index),
                        label: {
                            Text("(index)")
                        })
                        .accentColor(.primary)
                }