KVKFlowCoordinators 0.2.1

KVKFlowCoordinators 0.2.1

Maintained by Sergei Kviatkovskii.



SwiftPM compatible License

KVKFlowCoordinators

SwiftUI flow coordinator to control navigation in your App.

Requirements

  • iOS 16.0+, iPadOS 16.0+, MacOS 13.0+ (supports Mac Catalyst)
  • Swift 5.0+

Installation

Swift Package Manager (Xcode 12 or higher)

  1. In Xcode navigate to FileSwift PackagesAdd Package Dependency...
  2. Select a project
  3. Paste the repository URL (https://github.com/kvyatkovskys/KVKFlowCoordinators) and click Next.
  4. For Rules, select Version (Up to Next Major) and click Next.
  5. Click Finish.

Adding Package Dependencies to Your App

Usage for SwiftUI

  • Import KVKFlowCoordinators.
  • Create an entities with type of navigation (for ex. enum SheetType: FlowTypeProtocol).
  • Create a coordinator that inherits from theFlowCoordinator base class if you want to use .sheet, .navigationDestination, .fullScreenCover. Or use a specific coordinator class SheetCoordinator, LinkCoordinator, CoverCoordinator, SheetAndLinkCoordinator, SheetAndCoverCoordinator, LinkAndCoverCoordinator.
  • Create a ViewModel if you need.
  • Create a CoordinatorView with the created coordinator.

To work with navigationLink use .navigationDestination(for: NavigationLinkType.self). The .navigationDestination(item: $item) doesn't work.

final class ContentCoordinator: FlowCoordinator<ContentViewModel.SheetType, ContentViewModel.LinkType, ContentViewModel.CoverType> {
    @Published var vm: ContentViewModel!
    
    private(set) var secondContentCoordinator: SecondContentCoordinator!
    
    init() {
        super.init()
        vm = ContentViewModel(coordinator: self)
        secondContentCoordinator = SecondContentCoordinator(parentCoordinator: self, title: "Second Coordinator")
    }
}

struct ContentCoordinatorView: View {
    @StateObject private var coordinator = ContentCoordinator()
    
    var body: some View {
        NavigationStack(path: $coordinator.path) {
            ContentView(vm: coordinator.vm)
                .fullScreenCover(item: $coordinator.coverType, content: { (item) in
                    SheetView(title: "Cover View")
                })
                .sheet(item: $coordinator.sheetType) { (item) in
                    switch item {
                    case .sheetFirst(let title):
                        SheetView(title: title)
                    }
                }
                .navigationDestination(for: NavigationLinkType.self) { (item) in
                    switch item {
                    case .linkFirstWithParams(let title):
                        NavigationLinkView(title: title)
                    case .linkSecond:
                        NavigationLinkView(title: "Test Second Link")
                    case .linkSecondCoordinator:
                        SecondContentCoordinatorView(coordinator: coordinator.secondContentCoordinator)
                    }
                }
        }
    }
}

final class ContentViewModel: ObservableObject {    
    private let coordinator: ContentCoordinator
    
    init(coordinator: ContentCoordinator) {
        self.coordinator = coordinator
    }
    
    func openFirstLink() {
        coordinator.linkType = .linkFirstWithParams("First Link View")
    }
}

struct ContentView: View {
    @ObservedObject var vm: ContentViewModel
    
    var body: some View {
        VStack(spacing: 30) {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            Text("Hello, world!")
            Button("Open Sheet") {
                vm.openSheetFirst(autoClose: false)
            }
            Button("Open Auto Close Sheet") {
                vm.openSheetFirst(autoClose: true)
            }
            Button("Open Cover") {
                vm.openCoverFirst()
            }
            Button("Open Link First") {
                vm.openFirstLink()
            }
            Button("Open Complex Btn Link") {
                vm.openComplexLink()
            }
            NavigationLink("Open Complex Nav Link",
                           value: ContentViewModel.LinkType.linkSecondCoordinator)
        }
        .padding()
    }
}

Author

Sergei Kviatkovskii

License

KVKFlowCoordinators is available under the MIT license