Swiftui 如何处理深度嵌套的导航链接
我的SwiftUI应用程序中有以下结构:Swiftui 如何处理深度嵌套的导航链接,swiftui,swiftui-navigationlink,Swiftui,Swiftui Navigationlink,我的SwiftUI应用程序中有以下结构: 主容器包含一个带有两个导航链接的导航视图,V1和V4。 从那里,我可以进入View1、View2和View3,我可以使用V1、V2和V3导航链接来浏览它们 我可以使用适当的导航链接转到ResultView,Result1,Result2,Result3 我有一个EnvironmentObject,它保存NavigationLinks的isActive属性的所有bool标志 当我到达ResultView时,我需要弹出视图并转到V4,直到稍后才能访问V1、
主容器
包含一个带有两个导航链接的导航视图
,V1
和V4
。
从那里,我可以进入View1
、View2
和View3
,我可以使用V1
、V2
和V3
导航链接来浏览它们
我可以使用适当的导航链接转到ResultView
,Result1
,Result2
,Result3
我有一个EnvironmentObject
,它保存NavigationLinks
的isActive
属性的所有bool
标志
当我到达ResultView时,我需要弹出视图并转到V4,直到稍后才能访问V1、V2和V3。
问题是发生了以下恶作剧(在iPhone8、iOS 13.4.1上):
- 如果我将
V1=false
设置为V4=true
,则NavigationView
会有一个奇怪的行为,它会弹出到以前的视图(View1、View2或View3),然后转到View4,然后返回到MainContainer
- 如果我只设置了
V1=false
,它会正确地弹出到主容器
我需要将V2、V3、Result1、Result2和Result3设置回false
,以确保我可以从V1重新启动,然后转到V2,等等。
此外,我的应用程序的一个要求是在进入ResultView
后,我绝对不能返回View1
、View2
和View3
我想到了两种可能的解决方案,但每一种都有它的警告:
在ResultView
中隐藏View 4
的NavigationLink
:在V4
中按back
时,如何防止返回View 1、2或3,并显示主容器
在设置V1=false
之后,使用计时器
或DispatchQueue.main.asyncAfter
来设置V4=true
:这似乎是一个老套的解决方案,但我已经尝试过了,它与不使用它有相同的效果,而且我不想看到来回转换(只是向前)
对于导航链接
的行为不正确,或者可能是更好的导航模型,您有什么建议吗
我已经实现了一个解决方案,在这个解决方案中,我使用了一个自定义的导航堆栈,我可以随时推送和弹出每个屏幕,问题是我丢失了一些转换,我真的希望通过使用标准的导航链接来实现这一点
我在这里留下一个例子
import SwiftUI
class NavigationCoordinator: ObservableObject {
@Published var goToFirstScreen: Bool = false
@Published var goToSecondScreen: Bool = false
@Published var goToThirdScreen: Bool = false
@Published var goToFourthScreen: Bool = false
}
struct ContentView: View {
@EnvironmentObject var coordinator: NavigationCoordinator
var body: some View {
NavigationView {
VStack {
Spacer()
NavigationLink(destination: FirstScreen(), isActive: self.$coordinator.goToFirstScreen) {
Text("Go To View1!")
}
Spacer()
NavigationLink(destination: FourthScreen(), isActive: self.$coordinator.goToFourthScreen) {
Text("Go to View4!")
}
Spacer()
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct FirstScreen: View {
@EnvironmentObject var coordinator: NavigationCoordinator
var body: some View {
NavigationLink(destination: SecondScreen(), isActive: self.$coordinator.goToSecondScreen) {
Text("Go to View2!")
}
}
}
struct SecondScreen: View {
@EnvironmentObject var coordinator: NavigationCoordinator
var body: some View {
NavigationLink(destination: ThirdScreen(), isActive: self.$coordinator.goToThirdScreen) {
Text("Go to View3!")
}
}
}
struct ThirdScreen: View {
@EnvironmentObject var coordinator: NavigationCoordinator
var body: some View {
Button("Go to View4") {
self.coordinator.goToFirstScreen = false
self.coordinator.goToFourthScreen = true
}
}
}
struct FourthScreen: View {
@EnvironmentObject var coordinator: NavigationCoordinator
var body: some View {
Button("Pop to root!") {
self.coordinator.goToFourthScreen = false
}
}
}
不知道这是否是Xcode 12独有的功能,但我找到了一个简单易行的答案,最近在这里回答了这个问题:
您只需使用navigationLink的标记
和选择
,并插入一个environmentobject来跟踪选择-将environmentobject选择设置为nil,以从任何后续子视图弹出回根视图。还允许您通过将Environment Object selection设置为导航链接的任何标记来转到任何导航链接。不知道这是否是Xcode 12独有的功能,但我找到了一个简单易行的问题答案,最近在这里得到了解答:
您只需使用navigationLink的标记
和选择
,并插入一个environmentobject来跟踪选择-将environmentobject选择设置为nil,以从任何后续子视图弹出回根视图。还允许您通过将Environment Object selection设置为导航链接的任何标记来转到任何导航链接。问题是因为我有一个Environment Object,它包含导航链接的isActive属性的所有布尔标志。-这不是导航堆栈现在的工作方式。你会提供带有期望值的演示可测试代码,以便修复它吗?在这里,使用ObserveObject是最受欢迎的想法,那么,你有其他方法的例子吗?关于代码,很抱歉,由于保密协议的原因,我不能分享。稍后我将尝试构建一个示例应用程序来展示我的意思。用示例更新。我想从第三个屏幕开始,用第一个屏幕和第四个屏幕重置堆栈。我该怎么做?问题是因为我有一个EnvironmentObject,它保存了NavigationLinks的isActive属性的所有bool标志。-这不是导航堆栈现在的工作方式。你会提供带有期望值的演示可测试代码,以便修复它吗?在这里,使用ObserveObject是最受欢迎的想法,那么,你有其他方法的例子吗?关于代码,很抱歉,由于保密协议的原因,我不能分享。稍后我将尝试构建一个示例应用程序来展示我的意思。用示例更新。我想从第三个屏幕开始,用第一个屏幕和第四个屏幕重置堆栈。我怎么做?