SwiftUI 실습 4
NavigationStack과 NavifationLink는 이동하는 뷰를 화면 전체에 채울 때 사용한다 아이폰에서는 이방법이 주로 사용되지만 아이패드나 아이폰 맥스의 가로방향일 때는 넓은 화면을 다채우기 때문에 더 많은 정보를 띄우지 못해 아쉬울 수 있다 넓은 디스플레이를 활용하기 위해서 멀티 컬럼 기반의 네비게이션을 사용할 수 있는 NavigationSplitView 컴포넌트가 존재한다
NavigationSplitView
NavigationSplitView의 목적은 멀티컬럼 기반 내비게이션 제공이다 사이드바A, 콘텐츠열B, 디테일C로 표현한다
목록 선택
보통 사이드바 또는 콘텐츠열에는 List뷰가 포함된다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import SwiftUI
struct ContentView: View {
@State private var colors = ["red","green","blue"]
@State private var selectedColor: String?
var body: some View {
NavigationSplitView {
List(colors, id:\.self,selection: $selectedColor){
color in Text(color).tag(color)
}
}detail: {
Text(selectedColor ?? "No color selected")
}
}
}
이 예시는 selection매개변수를 통해서 선택된 열을 추적할 수 있다 여기서 tag( )수정자가 이용되었는데 이 수정자는 List, Picker및 TabView에서 선택 가능한 항목을 구별하기 위해 사용된다 이를 통해서 selectedColor에 값이 전달된다
리스트 선택시 오른쪽화면을 출력한다
3열 분할 네비게이션
프로젝트 데이터 추가하기
카테고리에 이름 아이콘을 저장하기위해 클래스를 선언한다 IconCategoty.swift파일을 생성한다
1
2
3
4
5
6
7
8
9
//IconCategoty.swift
import SwiftUI
import Foundation
struct IconCategory: Identifiable, Hashable {
let id = UUID()
var categoryName: String
var images: [String]
}
이제 contentView에서 내용을 추가한다
1
2
3
4
5
6
7
8
9
// ContentView.swift
import SwiftUI
struct ContentView: View {
@State private var categories = [
IconCategory(categoryName: "Folders", images: ["questionmark.folder.ar", "questionmark.folder", "questionmark.folder.fill.ar", "floder.fill.bage.gear"]),
IconCategory(categoryName: "Circles", images: ["book.circle", "books.vertical.cicrle", "books.vertical.circle.fill", "book.circle.fill"]),
IconCategory(categoryName: "Clouds", images: ["cloud.rain", "cloud.drizzle.fill", "cloud.fill"])]
}
네비게이션 뷰 추가
데이터를 추가했으니 view를 넣어야한다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// ContentView.swift
import SwiftUI
struct ContentView: View {
@State private var categories = [
IconCategory(categoryName: "Folders", images: ["questionmark.folder.ar", "questionmark.folder", "questionmark.folder.fill.ar", "floder.fill.bage.gear"]),
IconCategory(categoryName: "Circles", images: ["book.circle", "books.vertical.cicrle", "books.vertical.circle.fill", "book.circle.fill"]),
IconCategory(categoryName: "Clouds", images: ["cloud.rain", "cloud.drizzle.fill", "cloud.fill"])]
@State private var selectedCategory: IconCategory?
var body: some View {
NavigationSplitView {
List(categories,selection: $selectedCategory) { category in
Text(category.categoryName).tag(category)
}
} content: {
} detail: {
}
}
}
리스트를 출력할때 카테고리 이름만 출력한다
콘텐츠 열에 목록 추가하기
현재 데이터는 존재하지만 표시한는 코드가 없어서 내용을 볼 수 없다 이 데이터를 콘텐츠 열에 추가한다 현재 선택된 아이콘의 이름을 추적할려면 상태 변수가 하나 필요하다 또한 선택하지 않으면 따로 메세지를 표시하도록 한다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@State private var selectedImage: String?
var body: some View {
NavigationSplitView {
List(categories,selection: $selectedCategory) { category in
Text(category.categoryName).tag(category)
}
} content: {
if let selectedCategory {
List(selectedCategory.images, id:\.self, selection: $selectedImage) { image in
HStack {
Image(systemName: image)
Text(image)
}.tag(image)
}
} else {
Text("Select a category to see the images.")
}
} detail: {
}
}
NavigationSplitView는 아이패드, 아이폰 맥스에서만 사이드 바가 보이고 일반 아이폰은 사이즈가 작아서 그냥 네비게이션 뷰로 보인다
디테일 열 추가
이제 컨텐츠 열까지 추가했으니 디테일 열을 추가한다
1
2
3
4
5
6
7
8
9
10
detail: {
if let selectedImage {
Image(systemName: selectedImage)
.resizable()
.aspectRatio(contentMode: .fit)
.padding()
} else {
Text("Select an image to see its details.")
}
}
추가 화면 구성
화면의 크기별로 초기 시작 화면이 다르다 아이폰 맥스에서는 앱의 처음부터 사이드바가 열리지 않고 디테일 페이지를 먼저 준다
초기 화면에서 사이드 바를 바로 띄우기위해 추가 설정을 한다
1
2
3
4
5
@State private var columnVisibility = NavigationSplitViewVisibility.all
var body: some View {
NavigationSplitView(columnVisibility: $columnVisibility) {
List(categories,selection:
위 설정후 아이폰에서 사진이 안보인다( 콘텐츠 열에 가려짐 ) 이미지를 보여주기 위해서
1
.navigationSplitViewStyle(.balanced)
이 스타일을 detail이 끝나는 곳에 추가한다
이미지가 현재 화면에 맞추어 표시된다