NavigationLinkとは、SwiftUIの遷移ボタン

著者: IT Sectr 公開日: 2026-06-25 読了時間: 6 分

NavigationLinkは、NavigationStackまたはNavigationViewで別の画面に遷移するために設計されたSwiftUIの制御要素です。Apple Developer Documentation, 2024によると、NavigationLinkは、押下時にターゲットViewをナビゲーションスタックに配置するボタンを作成します。iOS 16+では、ターゲットViewの早期初期化を避けるために、destinationを直接使用するのではなく、valueとNavigationDestinationを組み合わせたNavigationLinkの使用が推奨されています。

重要なポイント

  • NavigationLink — SwiftUIで別の画面に遷移するボタン
  • 2つの形式 — destination:label: と value:label:
  • Value形式 iOS 16+ (NavigationStack) で推奨
  • Destination形式 Viewの早期初期化を引き起こす
  • 自動開示矢印 Listでの表示

NavigationLinkは、押下時にナビゲーション遷移を開始するViewです。NavigationStack内でNavigationLinkを押すと、ターゲット画面がスタックに配置され、システムの戻るボタンが表示されます。NavigationLinkはiOS 13から存在し、SwiftUIにおけるユーザーナビゲーションの主要な方法です。

NavigationLinkはUIButtonを継承していません — コンテキストに自動的に適応するSwiftUIのViewです。List内では、NavigationLinkは開示インジケータとともに表示されます。リストの外では、NavigationLinkは通常のボタンとして動作しますが、ナビゲーション動作を備えています。

SwiftUI Lab (2024)によると、NavigationLinkは、Text、Image、VStackに次いで、SwiftUIアプリケーションで最も使用されるViewの1つです。初期化形式の違いを理解することは、パフォーマンスと予測可能なナビゲーション動作にとって重要です。

NavigationLinkの内部動作

押下されると、NavigationLinkは最も近いNavigationStackまたはNavigationViewに関連付けられたナビゲーションスタックに値(またはdestination)を追加します。SwiftUIはEnvironmentValueを使用して、View階層全体にナビゲーションパスを渡します。NavigationLinkはEnvironmentからこのパスを読み取り、押下時にそれを変更します。

NavigationLinkには2つの主要な形式があります:destination(ターゲットViewを直接指定)とvalue(NavigationDestinationの値)。形式の選択は、iOSのバージョンとナビゲーションアーキテクチャに依存します。

形式初期化子iOS 13–15iOS 16+
DestinationNavigationLink(destination:label:)推奨非推奨
ValueNavigationLink(value:label:)利用不可推奨
IsActiveNavigationLink(isActive:destination:label:)プログラムによるナビゲーション非推奨

Destination形式(iOS 13+):NavigationLink(destination: DetailView(), label: { Text("Open") })。この形式は、ユーザーがリンクをクリックしていなくても、NavigationLinkをレンダリングするときにDetailViewを即座に作成します。これによりViewの早期初期化が発生し、ターゲットViewがその初期化子で重い処理を実行する場合にパフォーマンスの問題が発生する可能性があります。

Value形式(iOS 16+):NavigationLink(value: "detail_42", label: { Text("Open") })。ターゲットViewは、リンクが押下され、SwiftUIが対応する.navigationDestinationを見つけたときにのみ作成されます。これにより早期初期化が防止され、ナビゲーションがより予測可能になります。

NavigationStackでのNavigationLink iOS 16+ではvalue形式への切り替えが必要です。ナビゲーション用のデータ型(String、Int、enum Route)を定義し、.navigationDestinationを介して遷移先を登録します。NavigationLinkはスタックに値のみを配置し、SwiftUIは押下時にターゲットViewを作成します。

swift
struct CatalogView: View {
    let categories: [String]

    var body: some View {
        List(categories, id: \.self) { category in
            NavigationLink(value: category) {
                Text(category)
            }
        }
        .navigationDestination(for: String.self) { category in
            CategoryView(name: category)
        }
    }
}

// Programmatic navigation:
struct DeepLinkView: View {
    @State private var path: [AppRoute] = []

    var body: some View {
        NavigationStack(path: $path) {
            HomeView()
                .navigationDestination(for: AppRoute.self) { route in
                    switch route {
                    case .detail(let id): DetailView(id: id)
                    case .settings: SettingsView()
                    }
                }
                .toolbar {
                    Button("Open Settings") {
                        path.append(AppRoute.settings)
                    }
                }
        }
    }
}

プログラムによるナビゲーション:パスに値を追加する(path.append経由)ことは、同じ値のNavigationLinkを押すことと同等です。これにより、ViewModel、Coordinator、またはプッシュ通知への応答からのナビゲーションを実装できます。

IsActive形式(NavigationLink(isActive:destination:label:))は互換性のために利用可能ですが、iOS 16+では推奨されません。パス配列またはNavigationPathへのBindingとともにvalue形式を使用してください。

List内のNavigationLinkは、行の右側に自動的に開示インジケータ(シェブロン)を表示し、押下すると別の画面に移動することをユーザーに示します。Listは矢印の表示を自動的に管理します — リストの外側にある通常のNavigationLinkには矢印がありません。

iOS 16では、NavigationLinkを伴うListは、List(data:rowContent:)内で自動的にvalue形式を使用します。List内でForEachを使用する場合も、開示インジケータが自動的に追加されます。この動作はモディファイアでは無効にできません — 矢印を削除するにはNavigationLinkをButtonに置き換えるしかありません。

Listでのdestination形式の問題:List内でNavigationLink(destination:label:)を使用すると、ユーザーがリンクをクリックしたかどうかに関係なく、すべての遷移先Viewがリストの読み込み時に即座に作成されます。多数の行を含むリストの場合、これにより初期読み込みが大幅に遅くなり、メモリ消費が増加する可能性があります。NavigationStackを使用したvalue形式がこの問題を解決します。

WWDC 2022(Session 10054)によると、Appleは新しいプロジェクトではNavigationStackとNavigationLinkのvalue形式の使用を推奨しています。これは、行数が多くなる可能性がある動的データを含むListにとって特に重要です。

パターン1:カスタムNavigationLinkの外観。 NavigationLinkは任意のViewをラベルとして受け入れ、リンクのカスタムデザインを作成できます。List内では、NavigationLinkを使用するときに自動的な開示インジケータが得られるため、特に便利です。

swift
NavigationLink(value: ProductRoute.detail(product)) {
    HStack {
        AsyncImage(url: product.imageURL)
            .frame(width: 60, height: 60)
        VStack(alignment: .leading) {
            Text(product.name).font(.headline)
            Text(product.price) .foregroundColor(.secondary)
        }
    }
    .padding(8)
}

パターン2:矢印なしのNavigationLink(カスタムボタン)。 開示インジケータが不要な場合は、プログラムによるナビゲーションにButtonを使用します:path.append(value)。これは、NavigationLinkが不自然に見えるカスタムインターフェース要素に便利です。

パターン3:条件付きナビゲーション。 空のdestinationを使用するか、特定の値に対して.navigationDestinationを追加しないことで、NavigationLinkをブロックできます。パスを介したプログラムによるナビゲーションでは、値を追加する前に条件をチェックできます。

Hacking with Swift (2024)によると、NavigationLinkの問題のほとんどは、古いプロジェクトでのdestination形式の使用に関連しています。NavigationStackに移行する際は、すべてのNavigationLink(destination:label:)をNavigationLink(value:label:)に置き換え、ルートレベルで.navigationDestinationを追加してください。

よくある質問

SwiftUIにおけるNavigationLinkとは?

NavigationLinkは、SwiftUIで別の画面に遷移するためのViewです。押下すると、ターゲット画面をNavigationStackまたはNavigationViewのナビゲーションスタックに配置します。destination(ターゲットView)とvalue(ルーティング値)の2つの形式をサポートしています。

NavigationLinkのどの形式が良いですか? destinationかvalueか?

Value形式(iOS 16+)が推奨されます:ターゲットViewはリンクのレンダリング時ではなく、押下時にのみ作成されます。Destination形式はViewを即座に作成するため、パフォーマンスの問題を引き起こす可能性があります。iOS 16+のプロジェクトでは、value + NavigationDestinationを使用してください。

なぜNavigationLinkはListで矢印を作成するのですか?

SwiftUIは自動的にList内のNavigationLinkに開示インジケータ(矢印)を追加し、ナビゲーションの可能性を示します。この動作は無効にできません。矢印が不要な場合は、path.append()を使用したプログラムによるナビゲーションでButtonを使用してください。

NavigationLinkでプログラムによるナビゲーションを行うには?

Bindingパスを持つNavigationStackを使用し、path.append(value)で値を追加します。これは同じvalueを持つNavigationLinkを押すことと同等です。プログラムによるナビゲーションにより、ディープリンク、プッシュ通知、Coordinatorパターンを実装できます。

NavigationLinkはパフォーマンスに影響しますか?

ターゲットViewがその初期化子で重い処理を実行する場合、destination形式はパフォーマンスに影響を与える可能性があります — すべての遷移先がリストのレンダリング時に作成されます。NavigationStackを使用したvalue形式は、押下時にのみViewを作成することでこの問題を解決します。50行以上のリストでは、その差は顕著です。

まとめ

  • NavigationLink — SwiftUI画面間のナビゲーション遷移用ボタン
  • Value形式 iOS 16+のNavigationStackで推奨
  • Destination形式 Viewを早期に作成 — 大規模リストでは避ける
  • 開示インジケータ — List内の自動矢印(無効不可)
  • プログラムによるナビゲーション path.append()でディープリンクとCoordinatorを実現
  • NavigationDestination データ型でターゲット画面を登録
  • IsActive形式 — 非推奨、iOS 16+ではvalue形式を使用

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください