[SwiftUI] NavigationView의 뷰 전환을 우회(?)하는 방법
SwiftUI에서 push, pop 형태로 뷰를 전환하기 위해서 NavigationView 라고 하는 View 구조체를 활용한다.
var body: some View {
NavigationView {
ScrollView {
NavigationLink {
PushedView()
} label: {
Text("이동하기")
}
}
}
}
뷰 이동이 발생할 뷰를 NavigationView로 감싸주고, 내부에서 NavigationLink 뷰로 이동 액션을 담당할 뷰 객체를 지정해준다. (web에서 <anchor /> 태그의 역할과 비슷하다.)
UIKit에서 뷰 전환을 위해 UINavigationController로 ViewController를 먼저 감싸줘야 한다는 개념이 SwiftUI에서도 비슷하게 적용된다.
다만, NavigationView로 이렇게 뷰 이동을 진행하는 경우, 이동되는 뷰 (자식뷰)가 이동 액션이 발생하기도 전에 미리 Init 되는 것을 확인할 수 있다.
유저가 이동할 지 안할지 모르기 때문에 NavigationLink에 연결된 뷰를 미리 init시켜 준비시켜두는 느낌이다.
자식뷰 Init 구문에 무거운 API 통신이 있거나, 스크롤뷰 안의 여러 뷰 객체가 모두 자식뷰를 가지고 있는 경우 뷰 이동 전에 과한 init이 발생할 수 있다.
이런 문제를 우회(?) 하기 위해서 뷰의 이동만을 담당하는 WrapperView 구조체를 사이에 둘 수 있다.
struct NavigatingViewWrapper<V: View>: View {
var navigatingContentHandler: () -> V
var body: some View {
navigatingContentHandler()
}
init(_ navigatingContentHandler: @autoclosure @escaping () -> V) {
self.navigatingContentHandler = navigatingContentHandler
}
}
NavigatingViewWrapper 객체는 init 구문에서 이동시킬 View를 반환하기만 하는 역할을 한다.
자신의 init을 부모 뷰에 맡기는 대신, 실제로 이동되어야 하는 뷰의 init은 실제 이동이 발생한 뒷 시점으로 미뤄줄 수 있다. (진짜 원하던 것)
Reaction
Comment
Share