【问题标题】:Come back to a specific View in SwiftUI (popToViewController)回到 SwiftUI 中的特定视图 (popToViewController)
【发布时间】:2020-01-02 03:52:01
【问题描述】:

在 SwiftUI 中是否可以返回到特定视图?假设我以这种方式拥有三个视图:

struct View1: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: View2()) {
                    Text("Navigate to View2")
                }
                .navigationBarTitle("View1")
            }
        }
    }
}

struct View2: View {
    var body: some View {
        NavigationLink(destination: View3()) {
            Text("Navigate to View3")
        }
        .navigationBarTitle("View2")
    }
}

struct View3: View {
    var body: some View {
        Text("View3!")
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    View1()
  }
}
#endif

导航来回工作:

View1->View2->View3
View3->View2->View1

可以直接从View3回到View1吗?我正在寻找的是类似于UIKit

func popToViewController(_ viewController: UIViewController, 
                animated: Bool) -> [UIViewController]?

【问题讨论】:

  • 是的,也不是。它需要一个NavigationView 和一个Publisherstackoverflow.com/questions/57334455/… 编辑:我还没有让它工作,但这是我今晚的任务。目前,我使用的是Notification 而不是PassthroughSubject
  • @dfd 感谢您的链接。我会尽快在我的示例中进行尝试。当然,我期待看到您能否为这个(我认为非常重要的)问题找到合适的解决方案。
  • 对此也感兴趣!!感觉 SwiftUI 有点缺乏导航

标签: ios swift uikit swiftui


【解决方案1】:

你可以通过调用两次dismiss方法返回2个步骤。

struct View3: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

    var body: some View {
        Button(
            action: {
                self.presentationMode.wrappedValue.dismiss()
                self.presentationMode.wrappedValue.dismiss()
            },
            label: { Text("Go back 2 steps") }
        )
    }
}

【讨论】:

    【解决方案2】:

    为了解决这个问题,我最终创建了一个名为 swiftui-navigation-stack (https://github.com/biobeats/swiftui-navigation-stack) 的开源项目。它包含NavigationStackView,一个模仿标准NavigationView 的所有导航行为的视图,添加了一些其他功能(所有功能都在repo 的自述文件中进行了解释)。要回答上面的问题,我们可以这样使用NavigationStackView

    假设我们必须实现这样的导航:

    View1 (push)-> View2 (push)-> View3 (push)-> View4 (pop)-> View2
    

    首先将您的第一个视图嵌入到 NavigationStackView 中(就像使用标准 NavigationView 一样):

    struct RootView: View {
        var body: some View {
            NavigationStackView {
                View1()
            }
        }
    } 
    

    让我们创建这些简单的视图来构建示例:

    struct View1: View {
        var body: some View {
            ZStack {
                Color.yellow.edgesIgnoringSafeArea(.all)
                VStack {
                    Text("VIEW 1")
                    Spacer()
                    PushView(destination: View2(), destinationId: "view2") {
                        Text("PUSH TO VIEW 2")
                    }
                }
            }
        }
    }
    
    struct View2: View {
        var body: some View {
            ZStack {
                Color.green.edgesIgnoringSafeArea(.all)
                VStack {
                    Text("VIEW 2")
                    Spacer()
                    PushView(destination: View3()) {
                        Text("PUSH TO VIEW 3")
                    }
                }
            }
        }
    }
    
    struct View3: View {
        var body: some View {
            ZStack {
                Color.gray.edgesIgnoringSafeArea(.all)
                VStack {
                    Text("VIEW 3")
                    Spacer()
                    PushView(destination: View4()) {
                        Text("PUSH TO VIEW 4")
                    }
                }
            }
        }
    }
    
    struct View4: View {
        var body: some View {
            ZStack {
                Color.white.edgesIgnoringSafeArea(.all)
                VStack {
                    Text("VIEW 4")
                    Spacer()
                    PopView(destination: .view(withId: "view2")) {
                        Text("POP TO VIEW 2")
                    }
                }
            }
        }
    }
    

    PushViewPopView 让您可以在视图之间导航,除此之外,它们还可以让您指定视图的标识符(以便您可以在需要时返回它)。

    以下是完整的例子,你可以复制粘贴到xCode自己试试:

    import SwiftUI
    import NavigationStack
    
    struct RootView: View {
        var body: some View {
            NavigationStackView {
                View1()
            }
        }
    }
    
    struct View1: View {
        var body: some View {
            ZStack {
                Color.yellow.edgesIgnoringSafeArea(.all)
                VStack {
                    Text("VIEW 1")
                    Spacer()
                    PushView(destination: View2(), destinationId: "view2") {
                        Text("PUSH TO VIEW 2")
                    }
                }
            }
        }
    }
    
    struct View2: View {
        var body: some View {
            ZStack {
                Color.green.edgesIgnoringSafeArea(.all)
                VStack {
                    Text("VIEW 2")
                    Spacer()
                    PushView(destination: View3()) {
                        Text("PUSH TO VIEW 3")
                    }
                }
            }
        }
    }
    
    struct View3: View {
        var body: some View {
            ZStack {
                Color.gray.edgesIgnoringSafeArea(.all)
                VStack {
                    Text("VIEW 3")
                    Spacer()
                    PushView(destination: View4()) {
                        Text("PUSH TO VIEW 4")
                    }
                }
            }
        }
    }
    
    struct View4: View {
        var body: some View {
            ZStack {
                Color.white.edgesIgnoringSafeArea(.all)
                VStack {
                    Text("VIEW 4")
                    Spacer()
                    PopView(destination: .view(withId: "view2")) {
                        Text("POP TO VIEW 2")
                    }
                }
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            RootView()
        }
    }
    

    结果是:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      • 2022-06-17
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      相关资源
      最近更新 更多