stack-navigation

main

Navigation library for UIKit and SwiftUI that operates based on Path state.
sunghyun-k/stack-navigation

Stack Navigation

Stack Navigation is a library for UIKit and SwiftUI that displays destinations based on the path state, similar to SwiftUI's NavigationStack.

Stack Navigation은 SwiftUI의 NavigationStack과 유사하게 Path 상태를 기반으로 Destination들을 표시하는 UIKit 및 SwiftUI 용 라이브러리입니다.

Requirements

  • Swift 5.7 or later
  • iOS 13 or later

Usage

With SwiftUI

Stack based navigation (Global destination)

  1. Add data collection property.

    데이터 컬렉션 프로퍼티를 추가합니다.

@State private var presentedParks: [Park] = []
  1. Bind the StackNavigationView to a data collection value and add a Destination using snNavigationDestination(for:destination:).

    StackNavigationView와 데이터 컬렉션 값을 바인딩하고, snNavigationDestination(for:destination:)을 사용하여 Destination을 추가합니다.

StackNavigationView(path: $presentedParks) {
  List(parks) { park in
    Button(park.name) {
      presentedParks.append(park)
    }
  }
  .snNavigationDestination(for: Park.self) { park in
    ParkDetails(park: park)
  }
}

Tree based navigation (Local destination)

  1. Add a bool property.

    Bool 프로퍼티를 추가합니다.

@State private var showDetails = false
var park: Park
  1. Add a modifier inside StackNavigationView.

    StackNavigationView 내부에 모디파이어를 추가합니다.

StackNavigationView(path: $presentedParks) {
  VStack {
    Text(park.name)
    Button("Show details") {
      showDetails = true
    }
  }
  .snNavigationDestination(isPresented: $showDetails) {
    ParkDetails(park: park)
  }
}

Change navigation title

Add snNavigationTitle(:) modifier in the Root View or Destination View.

snNavigationTitle(:) 모디파이어를 Root View 또는 Destination View에 추가합니다.

content.snNavigationTitle(park.name)

With UIKit

Stack based navigation (Global destination)

  1. Initialize the navigation in the container such as AppDelegate, ViewController, etc.

    내비게이션을 사용할 컨테이너(AppDelegate, ViewController 등)에서 이니셜라이즈합니다.

let navigationController = StackNavigationController(
  rootViewController: rootViewController,
  initialPath: viewModel.presentedParks,
  destination: { ParkDetailsViewController(park: $0) }
)
  1. If you want to change the state when path changed, use the StackNavigationControllerDelegate.

    Path가 변경될 때 뷰모델의 상태에 반영하고 싶다면 StackNavigationControllerDelegate를 사용합니다.

extension AppDelegate: StackNavigationControllerDelegate {
  func navigationController(didChangePath changedPath: [Park]) {
    viewModel.presentedParks = changedPath
  }
}
  1. When the Path of the view model changes, call the updateStacks(using:) method to update the view.

    뷰 모델의 Path 변경시 updateStacks(:) 메서드를 호출하여 뷰를 업데이트합니다.

let pathUpdate = viewModel.$presentedParks
  .sink { [weak navigationController] newPath in
    navigationController?.updateStacks(newPath)
  }

Tree based navigation (Local destination)

Use pushViewController as usual.

기존 처럼 pushViewController를 사용합니다.

Move between UIKit and SwiftUI (Tree based)

Pushing SwiftUI View from UIViewController

Create a NavigationBindingController using SwiftUI views and push it.

SwiftUI 뷰를 사용해 NavigationBindingController를 생성하고 Push합니다.

let parkDetailsView: some View = ParkDetails(park: park)
let bindingController = NavigationBindingController(content: parkDetailsView)
navigationController?.pushViewController(bindingController, animated: true)

Pushing UIViewController from SwiftUI view

Define a Destination View Controller using the snNavigationDestination(isPresented:destinationViewController:) modifier.

snNavigationDestination(isPresented:destinationViewController:) 모디파이어를 사용하여 Destination View Controller를 정의합니다.

content
  .snNavigationDestination(isPresented: $showDetails) {
    ParkDetailsViewController(park: park)
  }

To do

  • NavigationLink
    • Local NavigationLink(destination:label:)
    • Global NavigationLink(value:label:)
  • NavigationPath
    • CodableRepresentation

Description

  • Swift Tools 5.7.0
View More Packages from this Author

Dependencies

  • None
Last updated: Sun Apr 14 2024 04:17:03 GMT-0900 (Hawaii-Aleutian Daylight Time)