第一次推送模式导航堆栈没有动画

dre*_*kka 6 swiftui

我有一个错误,我正在呈现NavigationStack模态 ( .sheet(...)) 并且推入堆栈的第一个视图无法设置动画。但是,如果我随后推送更多视图或弹出回来,它就会按预期进行动画处理。它似乎与视图模型中的堆栈路径相关@Publish,因为如果我将路径作为@State视图中的属性,它就可以正常工作。

\n

在此 gif 中,您可以看到,当 View2 第一次出现时,它没有动画,但随后它就会动画。

\n

在此输入图像描述

\n

这是生成上述 gif 的代码,我很感兴趣是否有人遇到过这种情况,并且有一个将路径保留在视图模型中的解决方案。

\n
//\n// Copyright \xc2\xa9 Derek Clarkson. All rights reserved.\n//\n\nimport SwiftUI\n\nstruct ContentView: View {\n\n    @State private var showModal = false\n\n    var body: some View {\n        Button("Show modal") {\n            showModal = true\n        }\n        .sheet(isPresented: $showModal) {\n            View1(viewModel: ViewModel())\n        }\n    }\n}\n\nenum Path {\n    case view1\n    case view2\n    case view3\n}\n\nclass ViewModel: ObservableObject {\n    @Published var path: [Path] = []\n    func next() {\n        path.append(path.count == 1 ? .view3 : .view2)\n    }\n}\n\nstruct View1: View {\n\n    @ObservedObject var viewModel:ViewModel\n\n    var body: some View {\n        NavigationStack(path: $viewModel.path) {\n            VStack {\n                Text("View 1").font(.largeTitle)\n                Button("Goto 2") {\n                    viewModel.next()\n                }\n            }\n            .navigationDestination(for: Path.self) { view in\n                switch view {\n                case .view2:\n                    View2(viewModel: viewModel)\n                case .view3:\n                    View3()\n                default:\n                    EmptyView()\n                }\n            }\n        }\n    }\n}\n\nstruct View2: View {\n\n    @ObservedObject var viewModel: ViewModel\n\n    var body: some View {\n        VStack {\n            Text("View 2").font(.largeTitle)\n            Text("This should animate on the first time, but doesn\'t!")\n            Text("Then if you navigate back and forth it animates fine!")\n            Button("Goto 3") {\n                viewModel.next()\n            }\n        }.padding()\n    }\n}\n\nstruct View3: View {\n\n    var body: some View {\n        VStack {\n            Text("View 3").font(.largeTitle)\n            Text("This should animate on")\n        }\n    }\n}\n\nstruct ContentView_Previews: PreviewProvider {\n    static var previews: some View {\n        ContentView()\n    }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

wor*_*dog 0

尝试这种方法,使用@StateObjectinContentView来“观察” ViewModel,并将其传递给View1such as View1(viewModel: viewModel)。同样重要的是,将 移动NavigationStack到 来ContentView制作View1根视图对我来说很有效。

struct ContentView: View {
    @State private var showModal = false
    @StateObject var viewModel = ViewModel() // <-- here

    var body: some View {
        Button("Show modal") {
            showModal = true
        }
        .sheet(isPresented: $showModal) {
            NavigationStack(path: $viewModel.path) {  // <-- here
                View1(viewModel: viewModel)  // <-- here
            }
        }
    }
}

struct View1: View {
    @ObservedObject var viewModel: ViewModel
    
    var body: some View {
        VStack {
            Text("View 1").font(.largeTitle)
            Button("Goto 2") {
                viewModel.next()
            }
        }
        .navigationDestination(for: Path.self) { view in
            switch view {
            case .view2:
                View2(viewModel: viewModel)
            case .view3:
                View3()
            default:
                EmptyView()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)