seong_hye, the developer

SwiftUI) 화면 전환 방식 본문

IOS/SwiftUI

SwiftUI) 화면 전환 방식

seong_hye 2022. 7. 19.

📘 Swift - SwiftUI) 화면 전환 방식

SwiftUI에서는 UIKit처럼 pushViewController나 present()를 쓰지 않고,

선언형 방식으로 화면 전환을 구현한다

방식 하나하나에 대해 알아보자


🔹 화면 전환 4가지 방식

방식 설명 사용 상황
NavigationLink 푸시(push) 전환 리스트 -> 상세
NavigationStack + 프로그래밍 전환 상태 기반 전환 조건 분기, 버튼 전환
.sheet 모달(modal) 전환 팝업처럼 위에 띄움
.fullScreenCover 전체 화면 모달 로그인, 온보딩 등

 


🔹 1. NavigationLink - Push 방식

버튼이나 텍스트처럼 NavigationLink 자체가 클릭 가능한 이동 UI가 됨

 

🔍 NavigationLink란?

SwiftUI에서 뷰 간의 탐색(push 전환)을 제공하는 링크형 UI 컴포넌트

버튼처럼 누르면 다른 화면(View)을 NavigationStack 내에서 push 형태로 전환함

NavigationStack {
	NavigationLink("상세보기") {
    	DetailView()
    }
}

📌 특징

- iOS 16부터는 NavigationStack 사용 필수

- 네비게이션 타이틀, 뒤로 가기 자동 제공

- 데이터 바인딩도 가능 (value, path 등)

 

✅ 화면 뒤로 가기 (pop)

SwiftUI는 NavigationLink 기반 push를 자동으로 관리함상단 네비게이션 바의 뒤로 버튼을 누르면 자동으로 이전 화면으로 이동 (pop)

 

또는 dismiss 활용하여 이동

@Environment(\.dismiss) var dismiss

Button("Back") {
	dismiss()
}

 

✅ iOS 13 ~ 15 사용자의 경우

NavigationView {
	NavigationLink("다음", destination: Text("이동한 화면"))
}
.navigationViewStyle(StackNavigationViewStyle())

➡️ iOS 16 이후에는 NavigationStack 으로 대체됨

 

 실행 화면


🔹 2. NavigationStack + 프로그래밍 전환(NavigationPath)

사용자 인터랙션 없이도 버튼 클릭이나 상태 변화에 따라 화면 이동을 자유롭게 제어 가능

NavigationLink의 한계를 극복한 방식으로, iOS 16이상부터 강력하게 활용 가능함

@State private var path = NavigationPath()

NavigationStack(path: $path) {
	VStack {
    	Button("다음 화면으로 이동") {
        	path.append("다음")
        }
    }
    .navigationDestination(for: String.self) { value in
    	Text("도착 : \(value)")
    }
}

📌 특징

- 코드 기반으로 화면 전환을 제어할 수 있음

- 조건부로 이동하거나, 여러 화면을 쌓을 때 유용

- SwiftUI의 동적 내비게이션 구현에 적합

 

핵심 개념 요약

요소 설명
NavigationStack 화면 전환을 관리하는 내비게이션 컨테이너 (iOS 16+)
NavigationPath 화면 이동 경로로 저장하는 스택 구조 (push, pop, popToRoot 등을 제어)
.navigationDestination(for:) 특정 타입이 push될 때 어떤 뷰를 보여줄 지 정의
path.removeLast(), path = .init() 화면 되돌리기(pop), 루트로 돌아가기 등 제어 가능

 

다양한 타입 전환 예제 (enum 사용)

.navigationDestination(for: Route.self) { route in
	switch route {
	case .detail(let id):
    	Text("상세 화면, ID: \(id)")
    case .profile(let name):
    	Text("프로필 화면, 이름: \(name)")
	}
}

📌 NavigationPath는 Hashable을 따르는 모든 타입(enum, struct 등)을

전환 대상으로 쓸 수 있어 구조화된 내비게이션 설계가 가능함

 

pop 관련 함수들

함수 설명
path.append(value) push
path.removeLast() pop
path.removeLast(n) n단계 pop
path = NavigationPath() root로 이동 (popToRoot)

🔹 3. .sheet - 모달 전환(하단 팝업)

UIKit의 present()에 해당하는 기능

화면 하단에서 위로 올라오는 모달을 쉽게 구현할 수 있게 해줌

 

🔍 .sheet 란?

SwiftUI에서 새로운 화면(View)을 현재 화면 위에 모달 형식으로 표시할 때 사용하는 Modifier

사용자는 이 모달을 위로 스와이프하거나, 직접 dismiss() 호출로 닫을 수 있음

@State private var showSheet = false

var body: some View {
	VStack {
		Button("시트 열기") {
    		showSheet = true
    	}
    	.sheet(isPresented: $showSheet) {
    		SheetView()
    	}
    }
}

📌 특징

- 화면의 일부를 가리는 모달 (아래에서 올라옴)

- 닫을 때는 dismiss() 호출하거나 @Environment(\.dismiss) 사용

 

닫기 방법 - dismiss()

import SwiftUI

struct SheetView: View {
	@Environment(\.dismiss) var dismiss
    
    var body: some View {
    	VStack {
        	Text("모달 화면")
           	Button("닫기") {
            	dismiss()
            }
        }
    }
}

➡️ dismiss()는 모달 또는 NavigationStack 상단 뷰를 닫는 SwiftUI 기본 기능

 

다양한 .sheet 바인딩 방식

1. .sheet(isPresneted:)

- Bool 바인딩

- true -> 모달 표시

 

2. .sheet(item:)

- Identifiable 타입을 바인딩해서 값을 넘기고 모달 표시

- item은 Identifiable 프로토콜을 따라야 함

@State private var selectedItem: Item?

.sheet(item: $seletedItem) { item in
	DetailView(item: item)
}

🔹 4. .fullScreenCover - 전체 화면 모달

.fullScreenCover(isPresented: $showFullScreen) {
	DetailView() 
}

📌 특징

- 전체 화면을 덮음 (기존 화면 안 보임)

- 뒤로 가기 제스처 없이, 사용자가 직접 닫기 버튼을 구현해야 함

- 로그인, 튜토리얼, 온보딩 등에 자주 사용됨


🔍  sheet와 fullScreencover 차이

항목 .sheet .fullScreenCover
전환 스타일 하단에서 올라오는 카드 모달 스타일 전체 화면을 완전히 덮음
뒤로가기 제스처 스와이프 아래로 닫기 가능 직접 dismiss 호출해야 함
닫기 버튼 제공 여부 기본적으로 스와이프 가능 닫기 버튼 직접 구현 필요
적합한 상황 설정창, 팝업, 상세뷰 등 로그인, 온보딩, 전체 덮는 화면 등

 

 실행 화면

1. sheet / 2. fullScreenCover


Comments