iPad나 Mac과 같은 넓은 화면에서 멀티컬럼 인터페이스를 구현할 때 NavigationSplitView는 정말 유용하다.
iOS 16부터 Swift에 도입된 이 뷰는 기존의 NavigationView를 대체하면서 더 강력한 기능을 제공한다.
SwiftUI에서 NavigationSplitView를 어떻게 효과적으로 사용할 수 있는지 살펴보자.
SwiftUI NavigationSplitView 사용법

NavigationSplitView의 기본 구조
NavigationSplitView는 최대 3개의 영역으로 구성된다:
- Sidebar – 주요 카테고리나 메뉴를 표시하는 영역
- Content – Sidebar에서 선택한 항목의 세부 콘텐츠를 보여주는 영역
- Detail – Content에서 선택한 항목의 상세 정보를 표시하는 영역
아이패드나 맥에서는 이 세 영역이 한 화면에 모두 표시될 수 있지만, 아이폰처럼 화면이 작은 기기에서는 하나의 영역만 표시되고 뒤로가기 버튼으로 이동하게 된다.
3개의 영역을 모두 사용한다면 Sidebar, Content, Detail 모두를 이용하지만, 2개의 컬럼으로 구성하고 싶을때는 Sidebar와 Detail을 이용한다. 이 점을 알고 있으면 좋다. 사이드바와 콘텐트가 아닌 사이드바와 디테일이다.
기본적인 NavigationSplitView 구현
가장 기본적인 형태의 NavigationSplitView는 이렇게 구현할 수 있다:
struct ContentView: View {
var body: some View {
NavigationSplitView {
// Sidebar 영역
List {
Text("메뉴 1")
Text("메뉴 2")
}
.navigationTitle("메뉴")
} content: {
// Content 영역
Text("콘텐츠 영역입니다")
.navigationTitle("콘텐츠")
} detail: {
// Detail 영역
Text("상세 정보 영역입니다")
.navigationTitle("상세")
}
}
}
상태를 통한 뷰 전환 구현하기
실제 NavigationSplitView를 이용한 앱에서는 사용자가 선택한 항목에 따라 다른 뷰를 보여줘야 한다. 이를 위해 상태(State) 값을 사용할 수 있다.
struct ContentView: View {
// 현재 선택된 콘텐츠 타입을 저장하는 상태 변수
@State private var selectedContent: ContentViewType? = nil
// 아이폰에서 현재 표시할 컬럼을 제어하는 상태 변수
@State private var preferredColumn: NavigationSplitViewColumn = .sidebar
var body: some View {
NavigationSplitView(columnVisibility: .constant(.all),
preferredCompactColumn: $preferredColumn) {
// Sidebar 영역
List(selection: $selectedContent) {
Button("소비 내역") {
selectedContent = .spendingHistory
// 아이폰에서는 다음 컬럼으로 이동
preferredColumn = .content
}
Button("구매 목록") {
selectedContent = .shoppingList
preferredColumn = .content
}
}
.navigationTitle("메뉴")
} content: {
// Content 영역 - 선택된 항목에 따라 다른 뷰 표시
if let selectedContent {
switch selectedContent {
case .spendingHistory:
SpendingHistoryView()
case .shoppingList:
ShoppingListView()
}
} else {
Text("왼쪽에서 메뉴를 선택해주세요")
}
} detail: {
// Detail 영역
Text("상세 정보 영역입니다")
}
}
}
// 콘텐츠 뷰 타입을 정의하는 열거형
enum ContentViewType: String, Identifiable {
case spendingHistory // 소비 내역 보기
case shoppingList // 구매 목록 보기
// case dashboard // 대시보드 보기 (필요시 추가)
// case detail // 세부 정보 보기 (필요시 추가)
var id: String { self.rawValue }
}
아이폰에서의 특별한 처리
아이폰은 화면 크기 제약으로 인해 한 번에 하나의 컬럼만 표시할 수 있다. 그래서 preferredCompactColumn
속성을 사용해 현재 표시할 컬럼을 지정해줘야 한다.
@State private var preferredColumn: NavigationSplitViewColumn = .sidebar
NavigationSplitView(preferredCompactColumn: $preferredColumn) {
// Sidebar 내용
} content: {
// Content 내용
} detail: {
// Detail 내용
}
버튼을 눌렀을 때 다음 컬럼으로 이동하도록 하려면:
Button("소비 내역 보기") {
selectedContent = .spendingHistory
// 아이폰에서 다음 화면으로 전환
if UIDevice.current.userInterfaceIdiom == .phone {
preferredColumn = .content
}
}
NavigationLink를 활용한 뷰 전환
상태 변수 외에도 NavigationLink를 사용해 뷰를 전환할 수도 있다.
swiftList {
NavigationLink(value: ContentViewType.spendingHistory) {
Label("소비 내역", systemImage: "chart.bar")
}
NavigationLink(value: ContentViewType.shoppingList) {
Label("구매 목록", systemImage: "cart")
}
}
.navigationDestination(for: ContentViewType.self) { viewType in
switch viewType {
case .spendingHistory:
SpendingHistoryView()
case .shoppingList:
ShoppingListView()
}
}
컬럼 가시성 제어하기
NavigationSplitView의 컬럼 표시 여부를 프로그래밍 방식으로 제어할 수도 있다.
@State private var columnVisibility: NavigationSplitViewVisibility = .all
NavigationSplitView(columnVisibility: $columnVisibility) {
// Sidebar 영역
} content: {
// Content 영역
} detail: {
// Detail 영역
}
// 버튼을 눌러 컬럼 가시성 변경
Button("사이드바만 보기") {
columnVisibility = .doubleColumn
}
NavigationSplitViewVisibility
는 NavigationSplitView에서 현재 어떤 컬럼들이 보여질지를 결정하는 열거형이.
.all
: 모든 컬럼(Sidebar, Content, Detail)을 표시.doubleColumn
: Sidebar와 Content만 표시 (Detail 숨김).detailOnly
: Detail 컬럼만 표시.automatic
: 시스템이 화면 크기에 따라 자동으로 결정
주로 사용자가 화면 레이아웃을 직접 조절할 수 있게 하고 싶을 때나 앱의 다양한 상태에 따라 적절한 레이아웃을 보여주고 싶을 때 사용하는 옵션이다.
NavigationSplitView 사용법을 마치며
SwiftUI의 NavigationSplitView는 다양한 화면 크기에 적응하는 멀티컬럼 인터페이스를 쉽게 구현할 수 있게 해준다.
상태 관리를 통해 다양한 뷰 전환 방식을 구현할 수 있고, 아이폰과 같은 작은 화면에서도 잘 동작하도록 만들 수 있다.
특히 iPad나 Mac 앱을 개발할 때 NavigationSplitView를 잘 활용하면 사용자 경험을 크게 향상시킬 수 있다.
NavigationSplitView에 대한 더 자세한 정보는 Apple 공식 문서에서 확인할 수 있다.