VDFlow 2.12.0

VDFlow 2.12.0

dankinsoid 维护。



VDFlow 2.12.0

  • Voidilov

VDFlow

说明

此存储库提供了一种新的简单方法来描述路由器

用法

使用 Step 结构化描述您的流程

struct TabSteps {
  var tab1 = Step()
  @Step var tab2 = SomeData()
  @Step var tab3 = NavigationSteps()
}

struct NavigationSteps {
  var screen1 = Step()
  var screen2 = Step()
  @Step(\.view1) var screen3 = PickerSteps()
}

struct PickerSteps {
  var view1 = Step()
  var view2 = Step()
}

只需更改任何属性的值或调用 select 来更新流程

//step is Step or StateStep 
step.tab2 = SomeData()
step.tab1.select()                 
step.tab3.screen3.view2.select()   
_step.select(\.tab3.screen3.view2) //or you can use KeyPath to any Step property

在具有 StateStep 属性包装器的 View 中使用流程结构体。StateStep 更新视图、存储您的流程结构体或从父视图绑定它。若要将流程绑定到视图层次结构,您需要使用 .step(...).stepEnvironment(...) 视图修饰符或创建具有 BindingStateView

struct RootTabView: View {
  
  @StateStep(\.tab1) var step = TabSteps()
  
  var body: some View {
    TabView(selection: $step.selected) {
      SomeView("0")
        .step(_step.tab1)
      
      Text("1")
        .tag(_step.$tab2)
      
      EmbededNavigation()
        .step(_step.$tab3)
    }.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
  }
}

struct EmbededNavigation: View {
  
  @StateStep var step = NavigationSteps()
  
  var body: some View {
    NavigationFlow($step.selected) {
      SomeView("0")
        .navigationTitle("0")
        .step(_step.screen1)
      
      Text("1")
        .navigationTitle("1")
        .tag(_step.screen2)
      
      //you can use Binding<Step<...>> and tag(...) instead of .step(...)
      EmbededPicker(step: $step.$screen3)
        .navigationTitle("2")
        .tag(_step.$screen3)
    }
  }
}

struct EmbededPicker: View {
  
  @StateStep var step: PickerSteps

  init(step: Binding<Step<PickerSteps>>) {
    _step = StateStep(step)
  }
  
  var body: some View {
    Picker("3", selection: $step.selected) {
      Text("0")
        .step(_step.view1)
      
      Text("1")
        .step(_step.view2)
    }.pickerStyle(WheelPickerStyle())
  }
}

您可以使用 .selectedKeyPath 交换

switch step.selected {
case \.tab1: ...
case \.tab2: ...
default: ...
}

但不能嵌套:case \.tab3.screen1: 不匹配

NavigationFlow

UINavigationController 包装器实现类似于堆栈的导航。

@State private var step = NavigationScreen.default

var body: some View {
  NavigationFlow($step) {
    Screen1()
      .tag(.screen1)

    Screen2()
      .tag(.screen2)

    Screen3()
      .tag(.screen3)

    ...
  }
  .navigationFlow(barColor: .black)
  .navigationFlow(barShadowColor: .blue)
  .navigationFlow(largeTitleFont: someUIFont)
  .navigationFlow(largeTitleColor: .white)
  .navigationFlow(titleFont: someUIFont)
  .navigationFlow(titleColor: .white)
  .navigationFlow(prefersLargeTitle: true)
  .navigationFlow(largeTitleMode: .always)
  .navigationFlow(backImage: someUIImage)
  .navigationFlow(showBackText: false)
  .navigationFlow(barPadding: EdgeInsets())
  .navigationFlow(barAccentColor: .red)
}

PresentFlow

UIViewController 的栈式展示流程包装器。

@State private var step = PresentScreen.default

var body: some View {
  PresentFlow($step, style: .native(.formSheet, .crossDissolve)) {
    Screen1()
      .tag(.screen1)

    Screen2()
      .tag(.screen2)

    Screen3()
      .tag(.screen3)

    ...
  }
}

FlowStack

ZStack 包装器,实现当前视图选择和交互动画。

@State private var step = FlowStep.default

var body: some View {
  FlowStack($step) {
    Screen1()
      .tag(.screen1)

    Screen2()
      .tag(.screen2)

    Screen3()
      .tag(.screen3)

    ...
  }
  .flowStackTransition(front: .move(edge: .top), back: .identity)
  .flowStackInteractive(hide: .top)
}

安装

  1. Swift 包管理器

创建一个 Package.swift 文件。

// swift-tools-version:5.0
import PackageDescription

let package = Package(
  name: "SomeProject",
  dependencies: [
    .package(url: "https://github.com/dankinsoid/VDFlow.git", from: "2.12.0")
  ],
  targets: [
    .target(name: "SomeProject", dependencies: ["VDFlow"])
  ]
)
$ swift build
  1. CocoaPods

在 Podfile 中添加以下行

pod 'VDFlow'

然后从 Podfile 目录运行 pod update

作者

dankinsoid, [email protected]

许可证

VDFlow 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。