The logo is contributed with 
 
SwiftUINavigator is a lightweight, flexible, and super easy library which makes SwiftUI navigation a trivial task.
Table of contents
Why?
Let's first explore the limitation of SwiftUI then explore the awesome features SwiftUINavigator provides.
SwiftUI Limitations
In SwiftUI, there are a lot of limitations:
- Transition navigations can not be disabled or customized.
 - Can not ignore adding the view to the back stack.
 - No navigation back to root view.
 - Can not navigate to a view using a specific ID.
 -  Inconsistent navigation when use 
NavigationLinka,.sheetand.fullScreenCover - Can not navigate programmatically.
 - Customizing the navigation bar is not trivial.
 
SwiftUINavigator is awesome
SwiftUINavigator has a lot of awesome features. Here's some of these features:
- Custom navigation transitions
 - Navigate to a view without adding it to the back stack.
 - Direct navigation without links
 - Direct navigation with links
 - Present sheets without having to declare a sheet modifier.
 - Dismiss to previous view.
 - Dismiss to root view.
 - Dismiss to a specific view using its ID.
 - Navigation Bars are built-in the library
 
Requirements
- iOS 13+
 - Swift 5.3+
 
Installation
   📦 
   Swift Package Manager
 
https://github.com/Open-Bytes/SwiftUINavigator.git
 
Usage
- Import 
SwiftUINavigator. 
import SwiftUINavigator 
- Declare 
NavigatorViewin the root view of the app. 
NavigatorView {
    HomeScreen()
} 
NavigatorViewsupports transition animations and other options. See NavigatorView
- Navigate to your destination view:
 
- Using 
NavigatorLink. 
NavigatorLink(destination: SomeView()) {
    // When this view is clicked, it will trigger 
    // the navigation and show the destination view
    ProductItemView()
} 
For more details about
Navigator, see NavigatorLink
- Or using 
Navigator 
@EnvironmentObject private var navigator: Navigator
navigator.navigate(SomeView()) 
For more details about
Navigator, see Navigator
- Dismiss (navigate back) to the previous view programmatically (using 
Navigator) or using a link (usingDismissLink). 
- Using 
NavigatorLink. 
DismissLink {
    Label("Back", systemImage: "chevron.backward")
            .foregroundColor(.blue)
} 
- Or using 
Navigator 
navigator.dismiss() 
For more details about dismissing, see Dismissing (Navigation Back)
NavigatorView
NavigatorView is the alternative of SwiftUI NavigationView implementing stack-based navigation with mote control and flexibility in handling more the navigation login
The public initializers
public init(
        transition: NavigatorTransitionType = .default,
        easeAnimation: Animation = .easeOut(duration: 0.2),
        @ViewBuilder rootView: () -> Root)
public init(
        navigator: Navigator,
        transition: NavigatorTransitionType = .default,
        easeAnimation: Animation = .easeOut(duration: 0.2),
        @ViewBuilder rootView: () -> Root) 
As you can see, you can customize the transition animation and easeAnimation.
NavigatorView(
        transition: .custom(push: .scale, pop: .slide),
        easeAnimation: .easeInOut) {
    HomeScreen()
} 
Important Note: the second initializers supports a
Navigatorinstance. This is important if you need to nest aNavigatorViewother than the root one. Keep in mind that if you didn't pass theNavigatorinstance, it will work, but it's recommended to pass it for consistent behavior is the whole app. In this case, you should pass the instance ofNavigatorusing theEnvironmentObjectas follows:
@EnvironmentObject private var navigator: Navigator
NavigatorView(navigator: navigator) {
    SomeView()
} 
For more details about
NavigatorTransitionType, see Navigation Transition Types
Navigator
The Navigator class is the heart of the library. It's injected to any view as EnvironmentObject.
@EnvironmentObject private var navigator: Navigator 
You can use Navigator directly to navigate programmatically to any view with 3 options
- Push view (Regular Navigation)
 
navigator.navigate(ProductDetailScreen(item: item))
// OR
navigator.navigate(ProductDetailScreen(item: item), type: .push()) 
You can specify an ID for the pushed view
navigate(SomeView(), type: .push(id: "Detail Screen")). Later, you can use this ID to navigate back to the view it's belonging to. See Dismissing (Navigation Back)
You can ignore adding the view to tha back stack
navigate(SomeView(), type: .push(addToBackStack: false)). When you navigate back this view won't be displayed. See Dismissing (Navigation Back)
- Present sheet
 
navigator.navigate(ProductDetailScreen(item: item), type: .sheet) 
- Present full sheet
 
navigator.navigate(ProductDetailScreen(item: item), type: .fullSheet) 
The navigation types are declared in NavigationType enum. See Navigation Types
NavigatorLink
The alternative of NavigationLink. It's a wrapper of Navigator. When clicked, it will navigate to the destination view with the specified navigation type.
NavigatorLink(destination: ProductDetailScreen(item: item)) {
    // When this view is clicked, it will trigger 
    // the navigation and show the destination view
    ProductItemView(item: item)
} 
Dismissing (Navigation Back)
You can dismiss the current view:
- Using 
NavigatorLink. 
DismissLink {
    Label("Back", systemImage: "chevron.backward")
            .foregroundColor(.blue)
} 
- Or using 
Navigator 
navigator.dismiss() 
Important Note: You have 4 options in dismissing the current view. for more details, see DismissDestination
DismissDestination
DismissDestination Defines the type of dismiss operation.
public enum DismissDestination {
    /// Navigate back to the previous view.
    case previous
    /// Navigate back to the root view (i.e. the first view added
    /// to the NavigatorView during the initialization process).
    case root
    /// Navigate back to a view identified by a specific ID.
    case view(withId: String)
    // Dismiss current presented sheet
    case dismissSheet
} 
You can pass your option to DismissLink or Navigator.dismiss()
DismissLink(to: .root) {
    Label("Back", systemImage: "chevron.backward")
            .foregroundColor(.blue)
}
navigator.dismiss(to: .root) 
Navigation Bar
Sine we don't use SwiftUI's NavgationView, the default navigation bar won't be displayed. To show the navigation bar you can use the library built-in bars or customize one.
SomeView()
        .navBar(
                style: .normal,
                leadingView: {
                    SomeView()
                }
        ) 
NavBarStylesupportsnormaland `large navigation bars.
Transitions
NavigatorView(transition: .custom(push: .scale, pop: .slide)) {
    SomeView()
} 
Navigation Types
This enum defines the supported navigation types
public enum NavigationType {
    /// Defines the regular navigation type.
    /// id: pass a custom ID to use when navigate back.
    /// addToBackStack: if false, the view won't be added to the back stack 
    /// and won't be displayed when dismissing the view.
    case push(id: String? = nil, addToBackStack: Bool = true)
    /// Present a sheet
    case sheet
    /// Present a full sheet
    @available(iOS 14.0, *)
    case fullSheet
} 
Navigation Transition Types
NavigatorTransitionType enum defines the supported transition types.
public enum NavigatorTransitionType {
    /// Transitions won't be animated.
    case none
    /// The default transition if you didn't pass one.
    case `default`
    /// Use a custom transition.
    case custom(push: AnyTransition, pop: AnyTransition)
} 
   👏 
   Contribution
 
All Pull Requests (PRs) are welcome. Help us make this library better.
License
click to reveal License
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
   https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 
 