Контроллер навигации SwiftUI заикается с двумя навигационными ссылками на строку списка
Я пытаюсь создать две ссылки NavigationLink в повторяющемся списке. У каждого свое предназначение. Весь код работает нормально, пока я не вставил вызов корневого представления в цикл List/ForEach. В этот момент навигация становится очень странной.
Попробуйте щелкнуть любую ссылку, а затем щелкните индикатор возврата вверху. Он перейдет на одну ссылку NavigationLink, а затем на другую. Иногда в другом порядке, а иногда он автоматически возвращается по одной из ссылок, а иногда не открывает второе подробное представление, пока вы не вернетесь из первого подробного представления. Это происходит как в режиме предварительного просмотра, так и при сборке и запуске приложения.
Я сократил код до самого простого, приведенного ниже. Если вы прокомментируете 2 строки, как указано в ContentView, вы увидите правильное поведение.
Я использую Catalina 10.15.5, xCode 11.6 с целевым приложением iOS 13.6.
Как я могу изменить код, чтобы он работал с циклом List/ForEach?
import SwiftUI
struct DetailView1: View {
var body: some View {
HStack {
Text("Here is Detail View 1." )}
.foregroundColor(.green)
}
}
struct DetailView2: View {
var body: some View {
HStack {
Text( "Here is Detail View 2.") }
.foregroundColor(.red)
}
}
struct RootView: View {
var body: some View {
HStack {
VStack {
NavigationLink(destination: DetailView1())
{ VStack { Image(systemName: "ant.circle").resizable()
.frame(width:75, height:75)
.scaledToFit()
}.buttonStyle(PlainButtonStyle())
Text("Tap for Detail 1.")
.foregroundColor(.green)
}
}
NavigationLink(destination: DetailView2())
{ Text("Tap for Detail 2.")
.foregroundColor(.red)
}
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
// Comment the following line for correct behavior
List { ForEach(0..<3) {_ in
RootView()
// Comment the following line for correct behavior
} }
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
ContentView()
.navigationBarTitle("Strange Behavior")
}
}
}
1 ответ
В вашем случае обе навигационные ссылки активируются сразу, пользователь нажимает строку, чтобы избежать этого, ниже возможен подход
Протестировано с Xcode 12 / iOS 14
Идея состоит в том, чтобы иметь одну ссылку, которая активируется программно, а место назначения выбирается динамически в зависимости от того, какая кнопка нажата.
struct RootView: View {
@State private var isFirst = false
@State private var isActive = false
var body: some View {
HStack {
VStack {
Button(action: {
self.isFirst = true
self.isActive = true
})
{ VStack { Image(systemName: "ant.circle").resizable()
.frame(width:75, height:75)
.scaledToFit()
}
Text("Tap for Detail 1.")
.foregroundColor(.green)
}
}
Button(action: {
self.isFirst = false
self.isActive = true
})
{ Text("Tap for Detail 2.")
.foregroundColor(.red)
}
.background(
NavigationLink(destination: self.destination(), isActive: $isActive) { EmptyView() }
)
}
.buttonStyle(PlainButtonStyle())
}
@ViewBuilder
private func destination() -> some View {
if isFirst {
DetailView1()
} else {
DetailView2()
}
}
}