Несколько ссылок для навигации, используемые в списках, не работают в SwiftUI

Я следил за учебником Apple по SwiftUI, и в разделе "Взаимодействие с UIKit" они заставили нас сделать карусель изображений (изображений ориентиров). Когда я попытался поэкспериментировать с этим, я сделал так, что, когда вы нажимаете на изображение, вы переходите к подробному представлению этого изображения. Я также добавил подпись под изображениями в карусели, и я хотел, чтобы эта подпись привела вас к небольшой заметке об этом конкретном ориентире при нажатии. Однако только заголовок привел вас к месту назначения, тогда как изображение ничего не сделало (хотя оно выделяется, когда вы нажимаете на него).

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

struct ContentView: View {
    @State var currentPage = 0  // Tracks page number of the Carousel.

    var body: some View {
        NavigationView {
            List {
                Carousel(currentPage: $currentPage)
                    .listRowInsets(EdgeInsets())

                Text("Page number: \(currentPage + 1)")  // Displays page number of Carousel.
            }
        }
    }
}
struct Carousel: View {
    @Binding var currentPage: Int

    var body: some View {
       VStack {
            PageView([Photo(), Photo()], currentPage: $currentPage)  // This is a view from the Apple Tutorial. I'll link it incase you want to check out the code for this.
                .equatable()  // This allows the Text which shows the page number to work. I've made the '==' operator to always return true for the sake of simplicity.
                .frame(height: 350)

            NavigationLink(destination: Text("Write-up about landmark")) {
                Text("\"Captions...\"")  // This changes in the real app depending on the page number. This NavigationLink always works and takes me to the correct page.
                    .font(.headline)
                    .padding(.bottom, 10)
            }
            .padding(.trailing)
        }
    }
}

struct Photo: View {
    var body: some View {
        NavigationLink(destination: Text("Landmark Detail")) {  // This NavigationLink doesn't work. It highlights when pressed down on, but doesn't take you anywhere.
            Image(systemName: "person")  // These are the respective landmarks in the real app.
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: UIScreen.screenWidth)  // Custom static property. It's equal to UIScreen.main.bounds.size.width
        }
    }
}

Ссылка на структуру PageView: https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit (раздел 3, шаг 3)
(Примечание: поскольку я отслеживаниеcurrentPage переменная в ContentView вместо того PageView, то currentPage переменная внутри PageView это Binding вместо State в моем коде)

Если кто-то может объяснить, как я могу заставить работать NavigationLink, дайте мне знать. Если вам лень писать код, вы можете просто объяснить, как это сделать, и я разберусь с этим оттуда.

Заранее спасибо!

1 ответ

Эта ссылка переходит в другую иерархию представлений, поэтому NavigationView ее не видит. Вот возможное решение (не проверено - колючее).

1) передать действие обратного вызова внутри фото

struct Photo: View {
    let action: () -> Void
    var body: some View {
        Button(action: action) {
            Image(systemName: "person")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: UIScreen.screenWidth)
        }
    }
}

2) Ввести действие обратного вызова из Carousel в Photo

struct Carousel: View {
    @Binding var currentPage: Int

    @State private var photoActivated = false // for in-code activation
    var body: some View {
       VStack {
            PageView([Photo(action: activateLink), Photo(action: activateLink)], currentPage: $currentPage)  // This is a view from the Apple Tutorial. I'll link it incase you want to check out the code for this.
                .equatable()  // This allows the Text which shows the page number to work. I've made the '==' operator to always return true for the sake of simplicity.
                .frame(height: 350)
                .background(
                    // hidden, to be activated by injected action
                    NavigationLink(destination: Text("Landmark Detail \(currentPage)"),
                        isActive: $photoActivated) { EmptyView() })

            NavigationLink(destination: Text("Write-up about landmark")) {
                Text("\"Captions...\"")  // This changes in the real app depending on the page number. This NavigationLink always works and takes me to the correct page.
                    .font(.headline)
                    .padding(.bottom, 10)
            }
            .padding(.trailing)
        }
    }

    private func activateLink() {
        self.photoActivated.toggle()
    }
}
Другие вопросы по тегам