2024.10.28 - [개발노트/iOS] - SwiftUI의 Navigation(화면 전환) - 선언형 구조와 명령형 구조의 차이
2024.11.10 - [개발노트/iOS] - SwiftUI의 Navigation - iPad version (feat. Custom Alert popup)
일전에 SwiftUI의 Navigation에 대해 검색해보다보니 LinkNavigator에 대한 글이 종종 보이더라.
그래서 조만간 한 번 써봐야지 생각하고 있었음.
한국에서 만든 거라 링크에 한국어 가이드도 있음b
프로젝트에 바로 적용한 건 아니고, 공부용 깃으로 만든 여기에 구현해봤다.
1. 패키지 의존성 추가 (SPM)
Xcode 메뉴에서 File - Add Package Dependencies 해도 되고,
Project Target - Package Dependencies 탭에서 + 버튼 눌러도 된다.
우측 상단 검색창에 패키지 URL 입력
URL: github.com/interactord/LinkNavigator.git
그러면 다운로드 시간 조금 있다가 이런 창이 뜰텐데 타겟 선택하고 Add Package 하면 된다
완료되면 프로젝트 왼쪽 내비게이터 하단에 의존성 정보 표시됨!
2. 초기 파일 추가 및 설정
1. AppDependency.swift 추가
import LinkNavigator
struct AppDependency: DependencyType { }
2. AppRouterGroup.swift 추가
import LinkNavigator
struct AppRouterGroup {
var routers: [RouteBuilder] {
[
]
}
}
3. AppDelegate 구현
import SwiftUI
import LinkNavigator
final class AppDelegate: NSObject {
var navigator: LinkNavigator {
LinkNavigator(dependency: AppDependency(), builders: AppRouterGroup().routers)
}
}
extension AppDelegate: UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
true
}
}
나는 만들어둔 파일이 없었어서 새로 생성했다.
4. 모든 화면이 ```navigator``` 프로퍼티를 주입받을 수 있도록 설정
import SwiftUI
import LinkNavigator
struct LNTestView: View {
let navigator: LinkNavigatorType
var body: some View {
...
}
}
HomeView, MainView 같은 역할의 View인데, Practice 프로젝트라서 이름을 이렇게 지었다.
5. 각 화면에 대한 ```RouteBuilder``` 생성
import SwiftUI
import LinkNavigator
struct LNTestRouteBuilder: RouteBuilder {
var matchPath: String { "home" }
var build: (LinkNavigatorType, [String: String], DependencyType) -> MatchingViewController? {
{ navigator, items, dependency in
return WrappingController(matchPath: matchPath) {
LNTestView(navigator: navigator)
}
}
}
}
6. 추가한 ```RouteBuilder```들을 2번에서 만든 ```AppRouterGroup```에서 관리
import LinkNavigator
struct AppRouterGroup {
var routers: [RouteBuilder] {
[
LNTestRouteBuilder(),
]
}
}
7. main 진입점 코드 수정
@main
struct Practice_SwiftUIApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
var navigator: LinkNavigator {
appDelegate.navigator
}
var body: some Scene {
WindowGroup {
navigator
.launch(paths: ["home"], items: [:]) // 'paths' 파라미터의 인자가 시작 페이지로 설정됩니다.
.onOpenURL { url in
// 딥링크 네비게이션이 필요한 경우,
// URL 편집은 여기서 수행합니다.
}
}
}
}
2-a. 빌드 결과
3. 실제 화면 전환 구현 - next(paths:items:isAnimated:)
3-a. 일반 화면 추가
Button {
navigator.next(paths: ["start"], items: [:], isAnimated: true)
} label: {
Text("시작 화면으로 이동")
}
별다른 커스텀 없이 NavigationView & NavigationLink 사용한 것처럼 추가된다.
3-b. navigationBarBackButtonHidden
기존 연습 프로젝트에 구현해뒀던 ```AnotherView```에는 커스텀 BackButton이 구현되어 있다.
그래서 별다른 작업 없이 backButtonHidden 옵션 주면 어떻게 될까 싶어서 시도해봄
![]() |
![]() |
이것도 별 특별한 점 없이 잘 적용된다.
다만 뒤로가기 버튼 눌러서 메인으로 돌아오면 NavigationBar 영역이 사라져있고,
그래서 시작화면 추가 버튼을 다시 눌러보면 뒤로가기 버튼이 안 보임
근데 사실 생각해보면 뒤로가기를 커스텀 하는 경우는 프로젝트 전체적으로 hidden 하고 적용할테니 문제될 건 없을 것 같은 느낌.
3-c. Custom Alert Popup
위 스크린샷에서도 보이는데,
기존에 구현해뒀던 뷰에 마침 저번에 테스트한 alert이 있어서 확인하는 김에 한 번 클릭해봤다.
![]() |
![]() |
LinkNavigator 사용 | NavigationView + NavigationLink 사용 |
오
fullScreenCover는 화면 전체가 덮이는 거라서 잘 덮이고, 시스템 알럿도 최상단에 뜨는 거라서 잘 뜨는데
ZStack으로 띄운 것만 이런 차이가 발생하더라.
혹시 LinkNavigator를 사용하게 되면 SafeArea 영역은 사용 못하는 걸까?
![]() |
![]() |
LinkNavigator 사용 | NavigationView + NavigationLink 사용 |
오..
그런가본데..?
```.ignoresSafeArea(.all)``` 옵션도 설정해봤는데 그냥 Navigation 영역을 침범할 뿐이었고
StatusBar랑 Indicator 영역은 여전히 흰색이더라.
일단 여기까지 하고,
next 외 다른 화면 전환 함수는 다음에 계속 포스팅해보는걸로.
'개발노트 > iOS' 카테고리의 다른 글
App Store Server API 사용을 위해 앱 개발자가 제공해줄것들 (2) | 2024.11.15 |
---|---|
Xcode Preview - No Selected Scheme (0) | 2024.11.13 |
SwiftUI의 Navigation - iPad version (feat. Custom Alert popup) (0) | 2024.11.10 |
SwiftUI의 Navigation(화면 전환) - 선언형 구조와 명령형 구조의 차이 (0) | 2024.10.28 |
SwiftUI로 Video Player 만들기 - UIViewRepresentable (1) | 2024.10.25 |