Несколько ссылок для навигации, используемые в списках, не работают в 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()
}
}