기어가더라도 제대로

[SwiftUI-기초] 프로젝트에서 TabView 두개 사용하기(Multiple TabView) 본문

SwiftUI - 기초

[SwiftUI-기초] 프로젝트에서 TabView 두개 사용하기(Multiple TabView)

Damagucci-juice 2025. 1. 22. 21:39

상황 설명

프로젝트에서 여러개의 탭을 구현해야하는 상황이 있을 수 있는데, 그럴 때 어떻게 하면 좋은지 적음

 

AppState, TabView, Key 

class AppState: ObservableObject {
    @Published var selectedSecondScreen: SecondScreen?
}

enum FirstScreen: Hashable, Identifiable, CaseIterable {
    case foo
    case bar
    case baz

    var id: Self { self }

    var image: String {
        switch self {
        case .foo:
            return "dot.square"
        case .bar:
            return "dot.viewfinder"
        case .baz:
            return "dot.scope"
        }
    }

    var text: String {
        switch self {
        case .foo:
            return "Foo"
        case .bar:
            return "Bar"
        case .baz:
            return "Baz"
        }
    }
}


enum SecondScreen: Hashable, Identifiable, CaseIterable {
    case fizz
    case buzz
    case fizzbuzz

    var id: Self { self }

    var image: String {
        switch self {
        case .fizz:
            return "ellipsis"
        case .buzz:
            return "ellipsis.rectangle"
        case .fizzbuzz:
            return "gauge.with.dots.needle.67percent"
        }
    }

    var text: String {
        switch self {
        case .fizz:
            return "Fizz"
        case .buzz:
            return "Buzz"
        case .fizzbuzz:
            return "Fizzbuzz"
        }
    }
}

 

편의상 열거형으로 각 화면을 대표하는 값을 선언

AppState.selectedSecondScreen 프로퍼티에 값을 할당해서 이 프로퍼티가 값이 있는지 없는지를 가지고 탭을 확인할 예정

 

TabView 선언

struct FirstTabView: View {
    @EnvironmentObject var appState: AppState

    var body: some View {
        TabView {
            ForEach(FirstScreen.allCases) { tab in
                if tab == .bar {
                    VStack {
                        Text("1번째 탭")
                            .font(.title)
                        Text(tab.text)

                        Button("2번째 탭 모드 설정") {
                            appState.selectedSecondTab = .fizz
                        }
                    }
                    .tabItem {
                        Text(tab.text)
                        Image(systemName: tab.image)
                    }
                    .tag(tab)
                } else {
                    VStack {
                        Text("1번째 탭")
                            .font(.title)
                        Text(tab.text)
                    }
                    .tabItem {
                        Text(tab.text)
                        Image(systemName: tab.image)
                    }
                    .tag(tab)
                }

            }
        }
    }
}

이 중 두번째 탭은 SecondScreen으로 향하는 버튼이 존재함

struct SecondTabView: View {
    @EnvironmentObject var appState: AppState

    var body: some View {
        TabView {
            ForEach(SecondScreen.allCases) { tab in
                if tab == .buzz {
                    VStack {
                        Text("2번째 탭")
                            .font(.title)

                        Text(tab.text)

                        Button("1번째 탭 모드 설정") {
                            appState.selectedSecondTab = nil
                        }
                    }
                    .tabItem {
                        Text(tab.text)
                        Image(systemName: tab.image)
                    }
                    .tag(tab)
                } else {
                    VStack {
                        Text("2번째 탭")
                            .font(.title)
                        Text(tab.text)
                    }
                    .tabItem {
                        Text(tab.text)
                        Image(systemName: tab.image)
                    }
                    .tag(tab)
                }
            }
        }
    }
}

그 반대도 마찬가지

 

ContentView에서 선언

struct ContentView: View {
    @EnvironmentObject var appState: AppState

    var body: some View {
        if appState.selectedSecondTab != nil {
            SecondTabView()
        } else {
            FirstTabView()
        }
    }
}

#Preview {
    @StateObject var appState = AppState()
    return ContentView()
        .environmentObject(appState)
}

AppState를 전역 환경 Object로 선언해서 이러한 사용이 가능함

AppState.selectedSecondTab 의 값이 존재하면 2번째 탭뷰를 보여주는 간단한 원리

그치만 화면 전환 애니메이션을 넣기 힘듦

 

전체코드

https://gist.github.com/Damagucci-Juice/cbf54870ba7bef323a90683400e923dd

 

MultiTabView.swift

GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

Comments