我试图通过编程的方式实现深度嵌套的导航栈。以下代码在手动导航时按预期工作(即:按链接)。当您按下“设置导航”按钮时,导航栈确实会更改,但不是预期的,并且最终导致堆栈损坏
[start -> b -> bbb]
,并在视图之间频繁切换。class NavState: ObservableObject {
@Published var firstLevel: String? = nil
@Published var secondLevel: String? = nil
@Published var thirdLevel: String? = nil
}
struct LandingPageView: View {
@ObservedObject var navigationState: NavState
func resetNav() {
self.navigationState.firstLevel = "b"
self.navigationState.secondLevel = "ba"
self.navigationState.thirdLevel = "bbb"
}
var body: some View {
return NavigationView {
List {
NavigationLink(
destination: Place(
text: "a",
childValues: [ ("aa", [ "aaa"]) ],
navigationState: self.navigationState
).navigationBarTitle("a"),
tag: "a",
selection: self.$navigationState.firstLevel
) {
Text("a")
}
NavigationLink(
destination: Place(
text: "b",
childValues: [ ("bb", [ "bbb"]), ("ba", [ "baa", "bbb" ]) ],
navigationState: self.navigationState
).navigationBarTitle("b"),
tag: "b",
selection: self.$navigationState.firstLevel
) {
Text("b")
}
Button(action: self.resetNav) {
Text("Set Nav")
}
}
.navigationBarTitle("Start")
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct Place: View {
var text: String
var childValues: [ (String, [String]) ]
@ObservedObject var navigationState: NavState
var body: some View {
List(childValues, id: \.self.0) { childValue in
NavigationLink(
destination: NextPlace(
text: childValue.0,
childValues: childValue.1,
navigationState: self.navigationState
).navigationBarTitle(childValue.0),
tag: childValue.0,
selection: self.$navigationState.secondLevel
) {
Text(childValue.0)
}
}
}
}
struct NextPlace: View {
var text: String
var childValues: [String]
@ObservedObject var navigationState: NavState
var body: some View {
List(childValues, id: \.self) { childValue in
NavigationLink(
destination: FinalPlace(
text: childValue,
navigationState: self.navigationState
).navigationBarTitle(childValue),
tag: childValue,
selection: self.$navigationState.thirdLevel
) {
Text(childValue)
}
}
}
}
struct FinalPlace: View {
var text: String
@ObservedObject var navigationState: NavState
var body: some View {
let concat: String = "\(navigationState.firstLevel)/\(navigationState.secondLevel))/\(navigationState.thirdLevel)/"
return VStack {
Text(text)
Text(concat)
}
}
}
我最初尝试解决导航过渡动画问题,但是如何禁用NavigationView推送和弹出动画表明这是不可配置的。
是否有任何合理的示例可以演示多级编程式导航工作?
编辑:我想要在这里获得的部分内容也包括正确工作的初始状态导航 - 如果我从外部环境中带有导航状态进入(即从通知中带有一些应用内上下文开始,或者从保存到磁盘的编码状态开始),那么我希望能够加载顶部View
并正确指向子视图。基本上,用真实值替换NavState
中的nil
。Qt的QML和ReactRouter都可以以声明方式完成此操作 - SwiftUI也应该可以。