git Repo: https://github.com/quokkaKyu/SwiftUINavigationStackCoordinator
뷰가 많아지면 관리하기가 힘들어집니다. 그래서 뷰의 이동만을 관리해줄 Coordinator가 필요했습니다. iOS16 이상 버전에서 사용할 SwiftUI NavigationStack에 Coordinator 패턴을 도입한 후기를 작성했습니다.
enum Destination: Hashable {
case firstView(number: Int)
case secondView
case thirdView(number: Int)
}
import Foundation
import Combine
final class Coordinator<T: Hashable>: ObservableObject {
@Published var paths: [T] = []
func push(_ path: T) {
paths.append(path)
}
func pop() {
paths.removeLast()
}
func pop(to: T) {
guard let found = paths.firstIndex(where: { $0 == to }) else {
return
}
let numToPop = (found..<paths.endIndex).count - 1
paths.removeLast(numToPop)
}
func popToRoot() {
paths.removeAll()
}
}
import SwiftUI
struct ContentView: View {
@ObservedObject private var coordinator = Coordinator<Destination>()
private let title = "ContentView"
var body: some View {
NavigationStack(path: $coordinator.paths) {
VStack {
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.white)
.navigationBarTitleDisplayMode(.large)
.toolbar(content: {
Button(action: {
coordinator.push(.firstView(number: 1))
}, label: {
Text("FirstView")
})
})
.navigationDestination(for: Destination.self) { destination in
switch destination {
case .firstView(let number): FirstView(number: number)
case .secondView: SecondView()
case .thirdView(let number): ThirdView(number: number)
}
}
}
.environmentObject(coordinator)
}
}
struct FirstView: View {
@EnvironmentObject private var coordinator: Coordinator<Destination>
private let title = "FirstView"
let number: Int
var body: some View {
VStack {
Text("\(number)")
Spacer()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.secondary)
.navigationTitle(title)
.toolbar(content: {
ToolbarItem(placement: .topBarTrailing, content: {
Button(action: {
coordinator.push(.secondView)
}, label: {
Text("SecondView")
})
})
})
.toolbar(content: {
ToolbarItem(placement: .topBarLeading, content: {
Button(action: {
coordinator.pop()
}, label: {
Text("ContentView")
})
})
})
.navigationBarBackButtonHidden()
}
}
이상으로 버전에서 SwiftUI NavigationStack에 Coordinator 패턴을 도입한 후기를 마치겠습니다. iOS16이상 SwiftUI 뷰의 이동을 구현하는데 도움이 되셨으면 좋겠습니다. 피드백은 언제든지 환영입니다.
Reference
https://www.curiousalgorithm.com/post/router-pattern-for-swiftui-navigation
https://medium.com/@zuxbcvf/exploring-scalable-swiftui-navigation-30f8438e9d6d