VDFlow
Description
This repository provides a new simple way to describe routers
Usage
Describe your flow as struct with Step
s
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()
}
Just change value of any property or call select
to update flow
//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
Use flow structs in a View
with StateStep
property wrapper. StateStep
updates view, stores your flow struct or binds it from parent view. To bind flow down the view hierarchy you need use .step(...)
, .stepEnvironment(...)
view modifiers or create StateView
with Binding
.
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())
}
}
You can switch .selected
with KeyPath
es
switch step.selected {
case \.tab1: ...
case \.tab2: ...
default: ...
}
but not nested: case \.tab3.screen1:
doesn't matched
NavigationFlow
UINavigationController
wrapper implementing stack like navigation.
@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
wrapper implementing stack like present flow.
@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
wrapper implementing selection of current view and interactive animations
@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)
}
Installation
Create a Package.swift
file.
// 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
Add the following line to your Podfile:
pod 'VDFlow'
and run pod update
from the podfile directory first.
Author
dankinsoid, [email protected]
License
VDFlow is available under the MIT license. See the LICENSE file for more info.