Tab안에 Navi? 혹은 Navi 안에 Tab?

SteadySlower·2022년 11월 7일
0

SwiftUI

목록 보기
32/64

이번에 Jwords를 만들면서 탭뷰를 도입하게 되었습니다. 오늘 학습할 단어리스트와 전체 단어리스트를 구분하게 위해서 인데요. 이 과정에서 갈림길에 마주치게 되었습니다. 탭뷰 안에 네비게이션 뷰를 넣을 것인가 아니면 네비게이션 뷰를 넣을 것인가인데요. 각각의 방법의 차이를 예제를 통해 알아보도록 하겠습니다.

코드

Tab 안에 Navi

import SwiftUI

struct MainView: View {

    var body: some View {
        TabView() {
            NavigationView {
                SomeNavigationLink()
                    .navigationTitle("첫번째 NavigationView")
                    .navigationBarTitleDisplayMode(.inline)
            }
            .tabItem { Image(systemName: "1.circle") }
            NavigationView {
                SomeNavigationLink()
                    .navigationTitle("두번째 NavigationView")
                    .navigationBarTitleDisplayMode(.large)
            }
            .tabItem { Image(systemName: "2.circle") }
        }
    }
}

struct SomeNavigationLink: View {
    
    var body: some View {
        NavigationLink("To Second Page") {
            Text("Second Page")
                .navigationTitle("Second Page")
        }
    }
}
import SwiftUI

struct MainView: View {
    
    var body: some View {
        NavigationView {
            TabView {
                SomeNavigationLink()
                    .tabItem { Image(systemName: "1.circle") }
                SomeNavigationLink()
                    .tabItem { Image(systemName: "2.circle") }
            }
            .navigationTitle("전체 Navigation View")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

struct SomeNavigationLink: View {
    
    var body: some View {
        NavigationLink("To Second Page") {
            Text("Second Page")
                .navigationTitle("Second Page")
        }
    }
}

특징

Tab 안에 Navi: Tab 마다 각각의 Navigation Title을 가질 수 있다.

내부에 NavigationView가 각각 있기 때문에 안에 있는 NavigationLink가 NavigationView 안에서의 가장 상위 View가 됩니다. NavigationTitle은 NavigationView 안에 있는 가장 상위 View인 각각의 NavigationLink에 서로 다른 navigation title을 줄 수 있습니다. 이는 BarButton도 마찬가지입니다. 즉 탭 페이지 마다 서로 다른 title과 서로 다른 Bar button이 필요할 때 적절한 방법이라고 볼 수 있습니다.

NavigationView는 최상위 View에 하나 뿐입니다. 따라서 TabView에서 navigation title이 보이게 하려면 TabView에 .navigationTitle을 적용해야 합니다. 즉 전체 TabView에 하나의 navigation title만 가질 수 있게 되는 것이죠.

만약에 Tab 마다 별도의 Navigation Title을 가지게 하려면 아래 처럼 selection과 tag을 활용해야 합니다.

struct MainView: View {
    
    @State var selectedTab: Int = 0
    
    var body: some View {
        NavigationView {
            TabView(selection: $selectedTab) {
                SomeNavigationLink()
                    .tabItem { Image(systemName: "1.circle") }
                    .tag(0)
                SomeNavigationLink()
                    .tabItem { Image(systemName: "2.circle") }
                    .tag(1)
            }
            .navigationTitle(selectedTab == 0 ? "첫번째" : "두번째")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

struct SomeNavigationLink: View {
    
    var body: some View {
        NavigationLink("To Second Page") {
            Text("Second Page")
                .navigationTitle("Second Page")
        }
    }
}


aws.com/secure.notion-static.com/494077d1-89a4-45b1-8459-79d414aaa7ec/3.gif)

Tab 안에 Navi: TabBar가 그대로 존재한다.

TabView가 최상위이므로 NavigationLink을 타고 다른 View로 이동한다고 해도 여전히 그 View는 TabView의 하위 View입니다. 따라서 TabBar도 그대로 존재하고 다른 Tab으로 이동할 수도 있습니다.

간단하게 생각하면 TabView 안에 두 개의 NavigationView가 병렬로 연결된 상태입니다. NavigationView가 2개 이기 때문에 View가 쌓이는 Stack도 2개입니다. 서로 영향을 전혀 주지 않습니다.

NavigationView 안에 TabView를 넣은 경우 NavigationView를 통해 다른 View로 이동하면 그 View는 더 이상 TabView의 하위 View가 아닙니다. TabView와는 관련이 없는 별도의 View가 되는 것이죠.

즉 NavigationView가 하나이므로 Stack도 하나이고 Stack 안에는 TabView 위에 다른 View가 올라오게 되는 것입니다.

profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글