[SwiftUI] Splash & Onboarding 화면 구현 리뷰 (Feat. 나만의 Todo)

2025. 5. 26. 14:23·iOS 개발/SwiftUI

이번 글에서는 제가 직접 만든 To-Do 앱의 Splash 화면과 Onboarding 화면을 소개해보려고 합니다.

제가 구성한 흐름은 다음과 같습니다:

  • 🌱 앱의 진입 흐름 (RootView) – 앱의 시작 구조와 화면 전환 관리
  • 🌊 SplashView – 심플하지만 강렬한 로딩 화면
  • 📖 OnboardingTabView – 앱의 주요 기능을 소개하는 페이지 뷰

이 순서대로 각 화면의 구성과 구현 방식을 차근차근 리뷰해보겠습니다. 그럼 지금부터 함께 살펴보시죠! 🚀


🌱 앱의 진입 흐름(RootView)

앱의 진짜 시작점은 @main 속성을 가진 N_VoiceMemoApp_SwiftUIApp 구조체입니다.

SwiftUI 앱의 생명주기에서 가장 처음 실행되는 이 지점에서는 RootView()를 호출하여

UI 흐름을 시작하게 됩니다.

@main
struct N_VoiceMemoApp_SwiftUIApp: App {
    var body: some Scene {
        WindowGroup {
            RootView()
        }
    }
}

네비게이션 흐름을 관리하기 위해 NavigationStack을 사용하였지만, 앱의 진입점인 N_VoiceMemoApp_SwiftUIApp에서는 사용하지 않고, 대신 RootView 내부에서 감싸도록 설계했습니다.

이렇게 구조를 나눈 이유는 앱 진입점에 과도한 책임을 지우지 않고,
화면 전환 및 상태 관리는 RootView에서 전담하도록 하여
코드의 역할 분리와 가독성을 높이기 위함입니다.

 

저는 앱 실행 시 Splash → Onboarding → Main 화면으로 자연스럽게 이어지도록 하기 위해

@State와 NavigationStack, 그리고 싱글톤 AppState를 활용했습니다.

struct RootView: View {
    @State private var showOnboarding = false // 온보딩 표시 여부
    @StateObject var appState = AppState.shared

    var body: some View {
        NavigationStack(path: $appState.navigationPath) {
            Group {
                if showOnboarding {
                    OnboardingTabView()
                } else {
                    SplashView()
                }
            }
            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
                    withAnimation {
                        showOnboarding = true
                    }
                }
            }
        }
    }
}

 

 

1. DispatchQueue

앱 시작 후 1.5초간 Splash 화면을 보여준 뒤, withAnimation을 통해 부드럽게 Onboarding 화면으로 전환되도록 구성한 점입니다.

.onAppear {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
            withAnimation {
                showOnboarding = true
            }
        }
    }

2. AppState

전체 흐름을 NavigationStack으로 감싸고, 경로(navigationPath)는 @StateObject로 관리되는 AppState를 통해 전역 상태로 관리합니다.

class AppState: ObservableObject {
    static let shared = AppState()
    @Published var navigationPath = NavigationPath()
}

🌊 SplashView

별도의 로딩 애니메이션 없이, 로고 이미지를 깔끔하게 보여주도록 구성했습니다.

struct SplashView: View {
    var body: some View {
        Image("logo")
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width: Constants.ControlWidth * 250)
    }
}

 

로고의 크기는 기기 너비에 따라 유동적으로 반응하도록 설정했으며, 저번에 포스팅했던 Figma 비율 그대로! 개발하는 Constants 구조체 만들기에 따라 설계된 Constants.ControlWidth 값을 활용하여 일관된 크기를 유지했습니다.


📖 OnboardingTabView

OnboardingView는 4단계 페이지형 화면으로 구현하였습니다.

이를 구현하기 위해 SwiftUI의 TabView와 PageTabViewStyle()을 활용했습니다.

TabView(selection: $currentPage) {
    OnboardingFirstView().tag(0)
    OnboardingSecondView().tag(1)
    OnboardingThirdView().tag(2)
    OnboardingLastView().tag(3)
}
.tabViewStyle(PageTabViewStyle())

 

 

1. TabView + .tag()

각 페이지를 구성하는 뷰(OnboardingFirstView 등)에 .tag()를 부여하고

TabView(selection:)과 연결함으로써 현재 어느 페이지에 있는지를 추적할 수 있게 했습니다.

@State private var currentPage = 0

currentPage는 사용자의 스와이프 동작에 따라 자동으로 바뀌며,

화면 하단의 페이지 인디케이터(동그라미 UI)의 상태도 함께 반응합니다.

ForEach(0..<4, id: \.self) { index in
    Circle()
        .fill(index == currentPage ? Color.key : Color.gray.opacity(0.5))
        .frame(width: 8, height: 8)
}

 

 

2. PageTabViewStyle()

TabView의 기본 스타일은 수평 스크롤로 여러 뷰를 보여줄 수 있지만,

여기서는 페이지 스타일로 바꾸기 위해 PageTabViewStyle()을 적용했습니다.

.tabViewStyle(PageTabViewStyle())

 

3. 화면 이동

Onboarding의 마지막 페이지인 OnboardingLastView에서는 “시작하기” 버튼을 누르면 메인 화면으로 전환되도록 구성했습니다.

이 때 AppState.shared.navigationPath.append(...)를 활용하여 전체 앱 흐름과 자연스럽게 연결되도록 했습니다.

Button {
    AppState.shared.navigationPath.append(onboardingType.main)
}

🎬 Splash & Onboarding 구현 영상

 

 


🧩 마무리

이번 포스팅에서는 제가 직접 만든 ToDo 앱의 시작 구조인

🌱 RootView, 🌊 SplashView, 📖 OnboardingView의 흐름과 구현 방식을 살펴보았습니다.

 

다음 포스팅에서는 SwiftUI에서 NavigationStack을 사용하는 경우와 사용하지 않는 경우의 차이점,

그리고 언제 어떤 방식이 더 적절한지에 대한 고민과 사례들을 정리해보려고 합니다.

 

앞으로도 꾸준히 기록하며 성장하는 개발자가 되기 위해 달려보겠습니다! 🚀

'iOS 개발 > SwiftUI' 카테고리의 다른 글

[SwiftUI] Todo 기능 리뷰 (Feat. 나만의 Todo)  (3) 2025.06.02
[SwiftUI] @Published 썼는데도 View가 안 바뀐다?  (0) 2025.05.30
[SwiftUI] Figma 비율 그대로! 개발하는 Constants 구조체 만들기  (1) 2025.05.24
뷰 상태변경 제 2장  (8) 2024.11.13
뷰 상태변경 제 1장  (0) 2024.11.13
'iOS 개발/SwiftUI' 카테고리의 다른 글
  • [SwiftUI] Todo 기능 리뷰 (Feat. 나만의 Todo)
  • [SwiftUI] @Published 썼는데도 View가 안 바뀐다?
  • [SwiftUI] Figma 비율 그대로! 개발하는 Constants 구조체 만들기
  • 뷰 상태변경 제 2장
Riu
Riu
안녕하세요 iOS 개발자를 꿈꾸는 Riu입니다. Github: woolnd
  • Riu
    Riu 개발노트
    Riu
  • 전체
    오늘
    어제
    • 분류 전체보기 (27) N
      • 티스토리 (2)
      • iOS 개발 (21) N
        • SwiftUI (9)
        • UIKit (6)
        • Combine (5)
        • Architecture (1) N
      • 알고리즘 (1)
      • 회고록 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    안드로이드
    SWIF
    cleanArchitecture
    ios개발
    UIKit
    Architecture
    ios
    SWIFT
    막자알림서비스
    시작
    figma
    알고리즘
    Combine
    앗차!
    티스토리
    구름톤유니브
    나만의todo
    SwiftUI
    회고록
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Riu
[SwiftUI] Splash & Onboarding 화면 구현 리뷰 (Feat. 나만의 Todo)
상단으로

티스토리툴바