NavigationLink の使い方

NavigationLink は NavigationStack 内で画面遷移を行うためのコンポーネントです。さまざまな初期化方法とカスタマイズ方法を解説します。

基本的な NavigationLink

最もシンプルな形式は、文字列と遷移先のビューを指定する方法です。

NavigationStack {
    NavigationLink("詳細画面へ") {
        DetailView()
    }
}

ラベルをカスタマイズ

label パラメータを使って、リンクの見た目を自由にカスタマイズできます。

NavigationLink {
    SettingsView()
} label: {
    Label("設定", systemImage: "gear")
}

複雑なレイアウトも可能です。

NavigationLink {
    UserDetailView(user: user)
} label: {
    HStack {
        Image(systemName: "person.circle.fill")
            .font(.largeTitle)
            .foregroundColor(.blue)
        
        VStack(alignment: .leading) {
            Text(user.name)
                .font(.headline)
            Text(user.email)
                .font(.caption)
                .foregroundColor(.gray)
        }
    }
}

List 内での NavigationLink

List の中で使用すると、自動的に右端に矢印(ディスクロージャインジケーター)が表示されます。

NavigationStack {
    List {
        NavigationLink("プロフィール") {
            ProfileView()
        }
        NavigationLink("通知設定") {
            NotificationSettingsView()
        }
        NavigationLink("プライバシー") {
            PrivacyView()
        }
    }
    .navigationTitle("設定")
}

データを渡す NavigationLink

遷移先のビューにデータを渡すことができます。

struct Product: Identifiable {
    let id = UUID()
    var name: String
    var price: Int
}

struct ProductListView: View {
    let products = [
        Product(name: "iPhone", price: 120000),
        Product(name: "iPad", price: 80000),
        Product(name: "MacBook", price: 200000)
    ]
    
    var body: some View {
        NavigationStack {
            List(products) { product in
                NavigationLink {
                    ProductDetailView(product: product)
                } label: {
                    VStack(alignment: .leading) {
                        Text(product.name)
                        Text(\(product.price)")
                            .font(.caption)
                            .foregroundColor(.gray)
                    }
                }
            }
            .navigationTitle("商品一覧")
        }
    }
}

struct ProductDetailView: View {
    let product: Product
    
    var body: some View {
        VStack {
            Text(product.name)
                .font(.largeTitle)
            Text(\(product.price)")
                .font(.title)
        }
        .navigationTitle(product.name)
    }
}

NavigationLink の状態を制御

isActive パラメータ(iOS 16 以前)や値ベースのナビゲーション(iOS 16 以降)を使って、プログラムから遷移を制御できます。

struct ContentView: View {
    @State private var showDetail = false
    
    var body: some View {
        NavigationStack {
            VStack {
                Button("詳細を表示") {
                    showDetail = true
                }
                
                NavigationLink(isPresented: $showDetail) {
                    DetailView()
                } label: {
                    EmptyView()
                }
            }
        }
    }
}
destination クロージャ

遷移先のビューを指定する。遷移が発生するまでビューは生成されない(遅延評価)。

label クロージャ

NavigationLink の見た目を定義する。任意の SwiftUI ビューを配置できる。

ディスクロージャインジケーター

List 内では自動的に表示される。非表示にしたい場合は別の方法が必要。

NavigationLink は宣言的に画面遷移を定義できる便利なコンポーネントです。次の記事では navigationTitle のカスタマイズについて詳しく解説します。