Sign In
상태
Empty
담당자
Empty
[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은 실제 이동이 발생한 뒷 시점으로 미뤄줄 수 있다. (진짜 원하던 것)
👍