PathPresenter

GitHub release (latest by date) GitHub top language Codacy Badge

swiftUIOnboarding.mp4

使用过渡、动画和 .sheet() 支持的纯 SwiftUI 路由。

在 SwiftUI 中,View 是状态的函数。路由也不例外。关于原理和内部机制的解释可以在我的博客上找到:

http://alexdremov.me/swiftui-navigation-is-a-mess-heres-what-you-can-do/

原因

优点

示例

视频中的示例:PathPresenterExample

视图层次结构通过 PathPresenter.Path() 结构进行管理。您可以使用 .append 方法将新视图推入其中,并使用 .removeLatest 从顶部删除视图。

在内部,视图的布局由 ZStack 管理,因此所有视图历史记录都是可见的。

可能的呈现方式

enum PathType {
  /**
   * Just show a view. No animation, no transition.
   * Show view above all other views
   */
  case plain
  
  /**
   * Show view with in and out transitions.
   * Transition animation also can be specified.
   */
  case animated(transition: AnyTransition, animation: Animation)
  
  /**
   * Show view in .sheet()
   * - Note: If you want to present several views in sheet,
   * you can create a second RoutingView and use it in sheet!
   */
  case sheet(onDismiss: Action)
}

完整示例


struct RootViewGitHub: View {
    @State var path = PathPresenter.Path()

    var body: some View {
        PathPresenter.RoutingView(path: $path) {
            // Root view. Always presented
            VStack {
                Button("Push") {
                    path.append(
                        VStack {
                            Text("Hello from plain push")
                            backButton
                        }.frame(width: 300, height: 300)
                         .background(.white)
                         .border(.red),
                        type: .plain
                    )
                }
                Button("Sheet") {
                    path.append(
                        VStack {
                            Text("Hello from sheet")
                            backButton
                        }.frame(width: 300, height: 300)
                         .background(.white)
                         .border(.red),
                        type: .sheet(onDismiss: {print("dismissed")})
                    )
                }
                Button("Left animation") {
                    path.append(
                        VStack {
                            Text("Hello from left animation")
                            backButton
                        }.frame(width: 300, height: 300)
                         .background(.white)
                         .border(.red),
                        type: .animated(transition: .move(edge: .leading),
                                        animation: .easeIn)
                    )
                }
            }
            .frame(width: 300, height: 300)
        }
    }
    
    var backButton: some View {
        Button("Back") {
            if !path.isEmpty {
                path.removeLast()
            }
        }
    }
}

过渡和动画示例

文档

代码大多经过注释,结构简单。去看看吧!

待办事项