참여 중인 회사 프로젝트에서 UIKit과 SwiftUI 프레임워크를 함께 사용하고 있다.
탭바와 같은 화면 전환은 UIKit을 사용하고 있지만 사실 SwiftUI의 내비게이션 기능을 제대로 사용해 본 경험이 없었다. 대신 틈나는 대로 직관로그 UI를 SwiftUI로 리팩토링하고 있어서 겸사겸사 화면 전환 관련 로직을 다루기 전 사전 학습으로 SwiftUI의 내비게이션을 조금 뜯어보기로 했다.
참고로, 이 글에서 다룰 Navigation은 iOS 16 이상을 기준으로 작성했다.
iOS 16 이전엔 NavigationView를 사용했지만, iOS 16에선 해당 API가 deprecated가 되었다.
이 글에선 NavigationView에 대한 내용은 다루지 않을 예정이다.
애플 공식 문서에 따르면, iOS 16 이전과 이후의 내비게이션 형식은 다음과 같이 변화했다.
현재 SwiftUI 내에서 내비게이션으로 화면 전환을 하는 방식은 크게 네 가지로 구분할 수 있다.
- NavigationStack + NavigationLink
- NavigationStack + NavigationDestination
- NavigationStack + NavigationLink + NavigationDestination
- NavigationStack + NavigationPath + NavigationDestination
정의
NavigationStack, NavigationLink, NavigationDestination
NavigationStack
: A view that displays a root view and enables you to present additional views over the root view.
애플 공식 문서에 따르면, NavigationStack은 루트 뷰(root view)를 표시하고 그 위에 추가 뷰들을 쌓을 수 있도록 하는 뷰다. 이름 그대로 "Stack"처럼 루트 뷰를 가장 아래에 두고 내비게이션을 기반으로 뷰들이 차례로 쌓이는 구조를 갖는다.
NavigationLink
: A view that controls a navigation presentation.
내비게이션 전환을 제어하는 뷰다. 클릭 또는 탭과 같은 사용자 상호작용에 의해 특정 목적지 뷰로 이동시키는 역할을 한다.
NavigationDestination
: Associates a destination view with a presented data type for use within a navigation stack.
NavigationStack 내에서 사용하기 위해 특정 데이터 타입과 연결된 목적지 뷰를 지정한다.
여기서 '데이터'는 전환될 뷰의 타입과 일치하는 데이터를 의미한다.
NavigationStack과 NavigationLink
NavigationStack은 루트 뷰를 기준으로 뷰 스택을 관리하고, NavigationLink는 그 뷰 스택에 새로운 뷰를 추가하는 역할을 수행한다. 따라서 NavigationStack과 NavigationLink는 세트라고 볼 수 있다.
정리하자면 NavigationStack 안에 NavigationLink를 구현해서,
1. 뷰 스택을 만든다 (NavigationStack)
2. 뷰를 추가한다. (NavigaitonLink)
위의 방식을 통하여 SwiftUI 내에서 네비게이션을 구현한다.
위 개념을 활용하여 기본적인 내비게이션 화면 전환 예제 코드를 구현해 보았다.
예시 1: NavigationStack과 NavigationLink의 기본 사용법
활용 api:
init(_:destination:) | Apple Developer Documentation
Creates a navigation link that presents a destination view, with a text label that the link generates from a localized string key.
developer.apple.com
가정:
- 루트 뷰는 NaviBaseView이며, 이 내비게이션 스택 위에 NaviYellowView와 NaviOrangeView를 각각 쌓아 내비게이션으로 화면 전환을 구현한다.
- 전환 방식은 RootView → ChildView로 Push/Pop 형태이다.
코드:
import SwiftUI
struct NaviBaseView: View {
var body: some View {
NavigationStack {
NavigationLink("YellowView") {
NaviYellowView()
}
NavigationLink("OrangeView") {
NaviOrangeView()
}
}
} // body
} // view
- NavigationStack 안에 NavigationLink를 사용하여 전환할 뷰들을 추가했다.
- NaviBaseView가 루트 뷰이므로, 시뮬레이션 영상에서 확인할 수 있듯이 이 뷰를 기준으로 뷰가 쌓여서 전환된다.
- NavigationLink("value")의 value 부분은 버튼과 같은 역할을 한다.
예제 2: 커스텀 버튼과 navigationDestination을 활용한 화면 전환
활용 api:
https://developer.apple.com/documentation/swiftui/view/navigationdestination(for:destination:)
navigationDestination(for:destination:) | Apple Developer Documentation
Associates a destination view with a presented data type for use within a navigation stack.
developer.apple.com
가정:
- NavigationLink의 텍스트가 아닌 커스텀 버튼을 눌러 하위 뷰로 화면 전환을 구현한다.
코드:
import SwiftUI
struct NaviBaseView: View {
// 1. 버튼 상태값
@State private var isButtonTapped: Bool = false
var body: some View {
NavigationStack {
// 2. 버튼 추가
Button(action: {
isButtonTapped = true
}, label: {
Text("Button")
.frame(width: 100, height: 48)
.background(.green)
})
// 3. 상태값 바인딩 + 이동할 뷰 추가
.navigationDestination(isPresented: $isButtonTapped) {
NaviYellowView()
}
}
} // body
} // view
- 버튼의 상태 값(isButtonTapped)을 트리거로 사용하여 내비게이션 화면 전환을 구현하는 기본 코드다.
References
Migrating to new navigation types | Apple Developer Documentation
Improve navigation behavior in your app by replacing navigation views with navigation stacks and navigation split views.
developer.apple.com
SwiftUI: NavigationLink, NavigationStack 알아보기
우리가 사용하는 앱은 대부분 1개 이상의 화면을 가진다. 이 화면들 사이를 자유롭게 이동하기 위해서는 Tab, modal 또는 Navigation 등을 사용할 수 있다.
medium.com
https://zeddios.tistory.com/1376
[SwiftUI] NavigationView ➡️ NavigationStack
안녕하세요 :) Zedd입니다. @available(iOS, introduced: 13.0, deprecated: 100000.0, message: "use NavigationStack or NavigationSplitView instead") public struct NavigationView : View where Content : View { ... } WWDC22에서 NavigationView가 depreca
zeddios.tistory.com
https://www.celinemoon.com/blog/navigationstack-and-navigationpath/
SwiftUI NavigationStack과 NavigationPath
SwiftUI에서 NavigationStack 사용하는 다양한 방법
www.celinemoon.com
'Dev > SwiftUI' 카테고리의 다른 글
[SwiftUI] LifeCycle (1) | 2024.10.14 |
---|---|
[SwiftUI] ObservableObject, ObservedObject, Published (5) | 2024.10.07 |
[SwiftUI] scrollTargetLayout과 ScrollTargetBehavior (0) | 2024.08.16 |
[SwiftUI] Property Wrapper 총정리 (0) | 2024.07.26 |
[SwiftUI] Frame (0) | 2024.07.22 |