NavigationStack과 NavigationSplitView에서 뷰 이동을 위해 NavigationLink를 사용할 수 있다. 

struct Fruit: Identifiable, Hashable {
    var id = UUID()
    let name: String
    let emoji: String
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(name)
    }
}

 

리스트에 보여주기 위한 기본 데이터 모델을 정의

 

struct FruitDetailView: View {
    let fruit: Fruit
    
    var body: some View {
        VStack {
            Text(fruit.emoji)
                .font(.largeTitle)
            Text(fruit.name)
        }
    }
}

 

데이터 모델을 보여주기 위한 View로서 navigation link에 의해 이동되는 화면


public init<S>(_ title: S, @ViewBuilder destination: () -> Destination) where S : StringProtocol

 

List의 목록에서 보여줄 title, 이동할 화면은 destination으로 정의해준다.

 

struct FruitView: View {
    private var fruits = [Fruit(name: "사과", emoji: "🍎"), Fruit(name: "오렌지", emoji: "🍊"), Fruit(name: "바나나", emoji: "🍌")]
    
    var body: some View {
        NavigationStack {
            List(fruits) { fruit in
                NavigationLink(fruit.name) {
                    FruitDetailView(fruit: fruit)
                }
            }
        }
    }
}

 

                NavigationLink {
                    FruitDetailView(fruit: fruit)
                } label: {
                    VStack {
                        Text(fruit.name)
                        Text(fruit.emoji)
                    }
                }

 

만약 단순 라벨이 아닌 커스텀 뷰를 리스트 목록으로 지정하고 싶은 경우 label 파라미터를 사용해 준다.

 

func navigationDestination<D, C>(
    for data: D.Type,
    @ViewBuilder destination: @escaping (D) -> C
) -> some View where D : Hashable, C : View

 

데이터 타입과 데이터 값을 기반으로 navigation link를 사용할 수 있다. 

 

struct FruitView: View {
    
    private var fruits = [Fruit(name: "사과", emoji: "🍎"), Fruit(name: "오렌지", emoji: "🍊"), Fruit(name: "바나나", emoji: "🍌")]
    
    var body: some View {
        NavigationStack {
            List(fruits) { fruit in
                NavigationLink(fruit.name, value: fruit)
            }
            .navigationDestination(for: Fruit.self) { fruit in
                FruitDetailView(fruit: fruit)
            }
        }
    }
}

 

NavigationLink에서 지정한 value에서의 값을 navigationDestination(for:destination:)으로 연결해 준다. LazyVStack, LazyHStack, List 등은 child view가 화면에 보여져야 할 때만 view를 렌더링 하므로 navigationDestination을 lazy 내부가 아닌 바깥에 정의해 줘야 한다. 

 

사용자가 NavigationLink를 탭하면 navigationDestination에 의해 상세 화면으로 이동한다.

 

참고 사이트 및 도서

 

Routing & Navigation in SwiftUI — the right way

Learn how to create a light & simple routing layer to handle your application’s navigation

blorenzop.medium.com

 

NavigationLink | Apple Developer Documentation

A view that controls a navigation presentation.

developer.apple.com