在我的 SwiftUI 应用程序中,我使用带有 navigationDestination 修饰符的 NavigationStack 在视图之间导航用户。在我的 AppState 中,我保存了一个 NavigationPath 数组的状态,这些数组在我的 ContentView 中与合并的发布者触发状态:
struct NavigationState: Equatable {
var path: [NavigationPath] = []
}
enum NavigationPath: Hashable {
case view1
case view2
case view3
case view4
}
为了在视图之间导航,我有一个
NavigationState
扩展。这些是我在 appState 上调用来更改 path
数组的方法:
extension AppState.NavigationState {
mutating func navigate(to destination: AppState.NavigationPath) {
if !path.contains(destination) {
path.append(destination)
}
}
mutating func pop() {
_ = path.popLast()
}
mutating func popToView2() {
path = [.view2]
}
}
这就是 ContentView 的样子:
struct ContentView: View {
@State private var navigationPath: [AppState.NavigationPath] = [.view1]
var body: some View {
NavigationStack(path: $navigationPath) {
View1()
.navigationDestination(for: AppState.NavigationPath.self) { path in
switch path {
case .view1:
View1()
case .view2:
View2()
case .view3:
View3()
case .view4:
View4()
}
}
}
.onReceive(navigationPathUpdate) {
self.navigationPath = $0
}
}
}
// MARK: - State Update
private extension ContentView {
var navigationPathUpdate: AnyPublisher<[AppState.NavigationPath], Never> {
container.appState.updates(for: \.navigationState.path)
}
}
updates
方法只是为了更新状态,我想详细解释并不重要。
最终,代码在所有 iPhone 和除 iOS 17.1.2(测试者的 iPhone 14 Pro)之外的所有 iOS 版本上都能完美运行。当用户调用
popToView2
应用程序崩溃时。我试图注释掉这个调用,在这种情况下,应用程序不会让测试人员崩溃,所以剩下的唯一猜测是 popToView2
做了一些坏事。我在 Xcode 中有一个崩溃日志,但它没有指出问题所在的确切代码行。 popToView2
用于注销后再次显示登录屏幕。
有人经历过类似的事情吗?
您应该为每种类型的值使用多个
navigationDestination
修饰符,而不是使用内部带有枚举/开关的单个修饰符。这些设计用于在整个 View
(模型)结构层次结构中声明。