SwiftUI 내에서 화면간의 이동은 NavigationView와 NavigationLink를 통해서 이루어진다. 화면, 즉 각각의 View를 push / pop 하는 방식으로 화면이 구성되는 것이다.
한편 하단 바는 가장 널리 알려진, 그리고 널리 쓰이는 어플리케이션 플로우 구성 방식이며 SwiftUI 내에서 TabView를 통해 구현된다.
NavigationView와 TabView를 통해 어플리케이션의 틀을 짜던 중에, NavigationLink를 통해 넘어간 다음 화면에 하단 바가 사라지지 않고 계속 남아 있는 현상을 발견했다.
생각보다 많은 시간을 쏟았지만, Hierarchy를 이해하고 나니 해결 과정은 생각보다 더 간단했다.
원래 코드는 이런 식으로 짜여져 있었다.
struct ContentView: View {
var body: some View {
TabView(selection: $tabSelection) {
NavigationView {
NavigationLink(destination: NavigatedView()) {
VStack {
Text("Navigate")
}
.navigationBarTitle("Tab1")
}
} // NavigationView
.tabItem { Text("Tab 1") }
.tag(Tabs.tab1)
.
.
.
} // TabView
} // View
지금의 계층 구조는 아래와 같이 되어 있는 것이다.
하지만, 내가(사실 디자이너가) 원하는 구조는 아래와 같았다.
실제로도 시중의 많은 앱들이 이런 플로우를 채택하고 있고, 그 이유는 사용자가 더 선호하기 때문일 것이다.
TabView 위에서 NavigationView가 빌드되었고, NavigationView 내에서 NavigationLink를 통해 넘어간 화면도 TabView 위에서 빌드되게 된 것이다. 따라서 TabBar가 남아 있을 수 밖에 없는 구조였던 것이다.
따라서, 코드를 아래와 같이 수정했다.
struct ContentView: View {
var body: some View {
NavigationView {
TabView(selection: $tabSelection) {
NavigationLink(destination: NavigatedView()) {
VStack {
Text("Navigate")
}
.navigationBarTitle("Tab1")
} // NavigationLink
.tabItem { Text("Tab 1") }
.tag(Tabs.tab1)
.
.
.
} // TabView
} // NavigationView
} // View
화면 이동 후, 하단 바가 잘 사라지는 것을 볼 수 있다.
언어를 처음 공부하다 보면, 언어의 문법과 구조에 대해 잘 모르기 때문에 우선 예제 코드들을 보고 따라하는 경우가 많다.
이번 트러블슈팅도, 사실 알고 보면 아무것도 아니고 당연하게 느껴지지만 TabView와 NavigationView가 어떻게 빌드되는지에 대한 이해가 없으면, 이런 구조를 파악하기는 커녕 NavigationLink 안에 NavigationView를 또 선언하여 필요 없는 네비게이션 바를 만들기도 하더라(부끄럽지만 내 이야기다).
생각보다 SwiftUI가 재미있다.
내가 1년 반 가량 사용했던 Flutter와 비슷해서 그런 것일수도 있다. 얼른 이 게으름을 극복하고 Flutter를 하며 느꼈던 점들도 정리해야겠다.
printf("Thank You!\n");
printf("Posted by Thirsty Developer\n");
근데 이렇게 하면 다음 화면에서 다크모드 전환했을때 탭 화면으로 튀어나가는 현상이 있어요.