【发布时间】:2020-04-11 16:12:19
【问题描述】:
我正在尝试按顺序获得深度嵌套的编程导航堆栈。当手动完成导航(即:按下链接)时,以下代码按预期工作。当您按下 Set Nav 按钮时,导航堆栈确实会发生变化 - 但不会像预期的那样 - 您最终会得到一个损坏的堆栈 [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)
}
}
}
我最初试图将导航过渡动画作为问题源来解决 - 但How to disable NavigationView push and pop animations 暗示这是不可配置的
那里有 >1 级程序化导航的合理示例吗?
编辑:我希望在这里获得的部分内容也是导航正常工作的初始状态 - 如果我从外部上下文中进入我希望反映的导航状态(即:从带有一些应用程序内上下文的通知,或者从保存到磁盘编码状态开始)然后我希望能够加载顶部View,导航正确指向正确的子视图。本质上 - 用实际值替换NavState 中的nils。 Qt 的 QML 和 ReactRouter 都可以声明式地做到这一点 - SwiftUI 也应该能够做到。
【问题讨论】:
-
有趣的是,如果您在视图中使用本地 @State 变量,这将完美运行...因此您可以通过初始化传递状态来进行深度链接。
-
用 DefaultNavigationViewStyle 就是。
-
这可能最近发生了变化——我为此提交了一份反馈报告,说如果其他框架可以做到这一点——SwiftUI 也应该这样做。他们最近发回了一些东西(我认为是 13.4.5 测试版),但我还没有跟进
-
这是个好消息。我期待着找出他们是否解决了这个问题。干杯!
标签: navigation swiftui ios-navigationview swiftui-navigationlink