### FlowStacks Migration: Previous API Example Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/Docs/Migration/Migrating to 1.0.md Demonstrates the structure of an application using the previous API of FlowStacks, where the Router handled both state management and view building, and the root screen was included in the routes array. ```swift enum Screen { case home case numberList case numberDetail(Int) } struct AppCoordinator: View { @State var routes: Routes = [.root(.home)] var body: some View { Router($routes, embedInNavigationView: true) { screen, _ in switch screen { case .home: HomeView() case .numberList: NumberListView() case .numberDetail(let number): NumberDetailView(number: number) } } } } ``` -------------------------------- ### FlowStacks SwiftUI Navigation Example Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/README.md Demonstrates the usage of FlowStacks for navigation, including push, sheet presentations, and navigating back to the root. It showcases FlowStack, FlowLink, and flowDestination modifiers. ```Swift import FlowStacks import SwiftUI struct ContentView: View { @State var path = FlowPath() @State var isShowingWelcome = false var body: some View { FlowStack($path, withNavigation: true) { HomeView() .flowDestination(for: Int.self, destination: { number in NumberView(number: number) }) .flowDestination(for: String.self, destination: { text in Text(text) }) .flowDestination(isPresented: $isShowingWelcome, style: .sheet) { Text("Welcome to FlowStacks!") } } } } struct HomeView: View { @EnvironmentObject var navigator: FlowPathNavigator var body: some View { List { ForEach(0 ..< 10, id: \.self) { FlowLink(value: number, style: .sheet(withNavigation: true), label: { Text("Show \(number)") }) } Button("Show 'hello'") { navigator.push("Hello") } } .navigationTitle("Home") } } struct NumberView: View { @EnvironmentObject var navigator: FlowPathNavigator let number: Int var body: some View { VStack(spacing: 8) { Text("\(number)") FlowLink( value: number + 1, style: .push, label: { Text("Show next number") } ) Button("Go back to root") { navigator.goBackToRoot() } } .navigationTitle("\(number)") } } ``` -------------------------------- ### FlowStacks Migration: New API Example Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/Docs/Migration/Migrating to 1.0.md Illustrates the updated structure for applications using the new FlowStacks 1.0 API. It shows the decoupling of view building into flowDestination and the exclusion of the root screen from the routes array. ```swift enum Screen: Hashable { case numberList case numberDetail(Int) } struct AppCoordinator: View { @State var routes: [Route] = [] var body: some View { FlowStack($routes, withNavigation: true) { HomeView() .flowDestination(for: Screen.self) { screen in switch screen { case .numberList: NumberListView() case .numberDetail(let number): NumberDetailView(number: number) } } } } ``` -------------------------------- ### FlowStack Initialization Options Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/Docs/Nesting FlowStacks.md Describes the different ways a FlowStack can be initialized, affecting how it manages navigation state. This includes using a FlowPath, a typed routes array, or no binding. ```swift 1. a binding to a `FlowPath`, which can support any `Hashable` data, 1. a binding to a typed routes array, e.g. `[Route]`, 1. no binding at all. ``` -------------------------------- ### Composable FlowStacks Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/README.md FlowStacks are designed for composability, allowing multiple flow coordinators, each with its own FlowStack, to be presented or pushed from a parent coordinator. Refer to Nesting FlowStacks documentation for more details. ```APIDOC Child flow coordinators: FlowStacks are composable, enabling parent coordinators to present or push child coordinators, each managing its own FlowStack. See Nesting FlowStacks for details. ``` -------------------------------- ### FlowNavigator Convenience Methods Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/README.md Provides convenience methods for easier navigation when interacting with a FlowNavigator, FlowPath, or routes array. These methods include push, presentSheet, presentCover, goBack, goBackToRoot, goBackTo, pop, and dismiss. ```APIDOC push: Pushes a new screen onto the stack. presentSheet: Presents a new screen as a sheet.† presentCover: Presents a new screen as a full-screen cover.† goBack: Goes back one screen in the stack. goBackToRoot: Goes back to the very first screen in the stack. goBackTo: Goes back to a specific screen in the stack. pop: Pops the current screen if it was pushed. dismiss: Dismisses the most recently presented screen. † Pass `embedInNavigationView: true` if you want to be able to push screens from the presented screen. ``` -------------------------------- ### FlowNavigator Usage in SwiftUI Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/README.md Demonstrates how to use the FlowNavigator environment object to programmatically control navigation within a FlowStacks-enabled application. Includes methods for pushing views, going back to specific routes, and returning to the root. ```Swift @EnvironmentObject var navigator: FlowPathNavigator var body: some View { VStack { Button("View detail") { navigator.push(.detail) } Button("Go back to profile") { navigator.goBackTo(.profile) } Button("Go back to root") { navigator.goBackToRoot() } } } ``` ```Swift @EnvironmentObject var navigator: FlowNavigator var body: some View { VStack { Button("View detail") { navigator.push(.detail) } Button("Go back to profile") { navigator.goBackTo(.profile) } Button("Go back to root") { navigator.goBackToRoot() } } } ``` -------------------------------- ### FlowStacks Internal Mechanism Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/README.md The library translates the array of routes into a hierarchy of nested NavigationLinks and presentation calls, building upon the technique used in NavigationBackport. ```APIDOC Internal Mechanism: Translates route arrays into NavigationLinks and presentation calls, expanding on NavigationBackport techniques. ``` -------------------------------- ### Deep-linking with FlowStacks Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/README.md FlowStacks handles deep-linking by working around SwiftUI's limitation of pushing only one screen per state update. It breaks down larger updates into smaller, supported updates, with optional delays. ```APIDOC Deep-linking: FlowStacks enables deep-linking to screens multiple layers deep by translating complex state updates into a series of smaller, supported updates. ``` -------------------------------- ### Binding Screen State with FlowStacks Source: https://github.com/johnpatrickmorgan/flowstacks/blob/main/README.md Configures the flow destination to work with a binding to its screen state in the routes array. This allows the screen to update its state within the routes array directly. Supports typed arrays of routes using enums and Binding transformations from SwiftUINavigation. ```swift import SwiftUINavigation struct BindingExampleCoordinator: View { @State var path = FlowPath() var body: some View { FlowStack($path, withNavigation: true) { FlowLink(value: 1, style: .push, label: { Text("Push '1'") }) .flowDestination(for: Int.self) { $number in EditNumberScreen(number: $number) // This screen can now change the number stored in the path. } } } } import FlowStacks import SwiftUI import SwiftUINavigation enum Screen: Hashable { case number(Int) case greeting(String) } struct BindingExampleCoordinator: View { @State var routes: Routes = [] var body: some View { FlowStack($routes, withNavigation: true) { HomeView() .flowDestination(for: Screen.self) { $screen in if let number = Binding(unwrapping: $screen, case: /Screen.number) { // Here `number` is a `Binding`, so `EditNumberScreen` can change its // value in the routes array. EditNumberScreen(number: number) } else if case let .greeting(greetingText) = screen { // Here `greetingText` is a plain `String`, as a binding is not needed. Text(greetingText) } } } } } struct HomeView: View { @EnvironmentObject var navigator: FlowPathNavigator var body: some View { VStack { FlowLink(value: Screen.number(42), style: .push, label: { Text("Show Number") }) FlowLink(value: Screen.greeting("Hello world"), style: .push, label: { Text("Show Greeting") }) } } } struct EditNumberScreen: View { @Binding var number: Int var body: some View { Stepper( label: { Text("\(number)") }, onIncrement: { number += 1 }, onDecrement: { number -= 1 } ) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.