NavigationViewは、画面間のスタックベースのナビゲーションを整理するためのSwiftUIコンテナコンポーネントです。NavigationViewは、自動ナビゲーションバー、タイトル、「戻る」ボタンを備えたナビゲーションスタックを作成します。iOS 16以降、AppleはNavigationStackの使用を推奨しています。詳細はAppleドキュメントをご覧ください。
重要なポイント
NavigationViewは、画面の階層をラップし、ナビゲーションインターフェースを提供するSwiftUIコンテナです。NavigationView内ではNavigationLinkが機能します。押すと現在の画面が新しい画面に置き換わる要素です。NavigationViewは自動的にタイトルと「戻る」ボタン付きのナビゲーションバーを追加します。
NavigationViewはSwiftUIとともにiOS 13で登場しました。概念的にUIKitのUINavigationControllerを置き換えますが、宣言的に実装されています。手動のpush/popではなく、開発者はNavigationLinkを使って画面間の関係を記述します。システムが自動的にスタックを管理します。
NavigationViewは、.navigationTitle、.navigationBarTitleDisplayMode、.toolbar、.searchableのモディファイアをサポートしています。iOS 16+では、AppleはNavigationStackを導入しました。これはNavigationViewのAPIを維持しつつ、NavigationPathによるプログラム的なスタック管理を追加します。iOS 15以下をサポートするプロジェクトでは、NavigationViewが唯一の選択肢です。
NavigationLinkは、NavigationViewまたはNavigationStack内でターゲット画面への遷移を作成するSwiftUI要素です。NavigationLinkを押すと、システムはターゲット画面をナビゲーションスタックに追加します。遷移アニメーションはiOSの標準的な右からのプッシュで、プラットフォームに適応します。
struct ContentView: View {
var body: some View {
NavigationView {
List(items) { item in
NavigationLink(destination: DetailView(item: item)) {
Text(item.title)
}
}
.navigationTitle("リスト")
}
}
}
struct DetailView: View {
let item: Item
var body: some View {
VStack {
Text(item.description)
.navigationTitle(item.title)
.navigationBarTitleDisplayMode(.inline)
}
}
}NavigationLinkは2つのパラメータを受け取ります:destination — ターゲットのView、label — ユーザーが押す要素。リストの場合、valueとNavigationLink(value:)を使った構文が便利です — セルを自動的に選択解除し、NavigationPathと連携します。
iOS 16で、AppleはNavigationViewの後継としてNavigationStackを発表しました。NavigationStackは宣言的な構文を維持しつつ、極めて重要な機能を追加します — NavigationPath型またはHashableの配列のpathプロパティによるプログラム的なスタック管理です。
| 機能 | NavigationView (iOS 13-15) | NavigationStack (iOS 16+) |
|---|---|---|
| プログラムによるpush | 不可、NavigationLinkのみ | 可、path.append(value)で |
| popToRoot | ルートへのdismissのみ | path.removeLast(path.count) |
| ディープリンク | 複雑な実装 | pathによる組み込みサポート |
| スタックの型付け | なし(destinationに任意のView) | あり(Hashable値の配列) |
| iPad SplitView | ColumnStyle / StackStyle | NavigationSplitView (iOS 16+) |
最小バージョンがiOS 16+のプロジェクトではNavigationStackを使用してください。iOS 14-15をサポートする場合はNavigationView。NavigationStackには旧バージョンの直接的な類似機能がないため、アップグレードには互換性の確認が必要です。
.toolbarと.navigationTitleのモディファイアがナビゲーションバーのコンテンツを制御します。.navigationTitleは画面のタイトルを設定し、.navigationBarTitleDisplayModeはスタイルを選択します:.large(大きい、デフォルト)または.inline(コンパクト、設定アプリのように)。.toolbarはボタン、検索、セグメントコントロールを追加します。
struct SettingsView: View {
var body: some View {
NavigationStack {
Form {
Section("プロフィール") {
Text("ユーザー名")
Toggle("通知", isOn: $notifications)
}
}
.navigationTitle("設定")
.navigationBarTitleDisplayMode(.large)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("保存") { save() }
}
ToolbarItem(placement: .navigationBarLeading) {
EditButton()
}
}
}
}
}.searchableは、ナビゲーションバーに検索バーを統合する別のモディファイアです。NavigationViewとNavigationStackの両方で動作します。スクロール時に検索は自動的に非表示になり、下にスワイプすると表示されます。Binding Stringによるリストフィルタリングをサポートしています。
NavigationPathはiOS 16+の型で、ナビゲーションスタックをHashable値のコレクションとして表現します。開発者はプログラム遷移のためにpathに要素を追加し、戻るために削除します。NavigationPathはディープリンク、プッシュ通知、状態復元をサポートしています。
struct AppNavigation: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
List(categories) { category in
NavigationLink("カテゴリ \(category.name)",
value: category)
}
.navigationTitle("カテゴリ")
.navigationDestination(for: Category.self) { category in
ProductListView(category: category)
}
.navigationDestination(for: Product.self) { product in
ProductDetailView(product: product)
}
}
// ディープリンクによるプログラム遷移
.onOpenURL { url in
guard let productId = DeepLinkParser.parse(url) else { return }
path.append(Product(id: productId))
}
}
}.navigationDestination(for:)は、画面を表示するデータ型を登録します。この型の値がpathに追加されると、システムが自動的にターゲットViewを作成します。このアプローチは明示的なNavigationLink(destination:)を置き換え、ナビゲーションを厳密に型付けします。
NavigationViewとNavigationStackはすべてのAppleプラットフォームで動作します:iOS、iPadOS、watchOS、tvOS、macOS。動作は画面に適応します。iPadでは、NavigationStackはNavigationSplitViewをサポートしており、UIKitのUISplitViewControllerを置き換え、ワイド画面に2列を表示します。
NavigationSplitView(iOS 16+)は画面をサイドバー(リスト)と詳細に分割します。iPhoneではサイドバーは非表示になり、NavigationLinkを介して詳細のみが表示されます。iPadではサイドバーと詳細がスプリットモードで同時に表示されます。
struct AdaptiveNavigation: View {
@State private var selectedCategory: Category?
var body: some View {
NavigationSplitView {
List(categories, selection: $selectedCategory) { category in
Text(category.name)
}
.navigationTitle("カテゴリ")
} detail: {
ProductListView(category: selectedCategory)
}
}
}NavigationSplitViewは各デバイスに最適な表示モードを自動的に選択します。ポートレートのiPhoneではスタック、ランドスケープのiPadとiPhoneではスプリット。開発者は異なるサイズクラスごとに個別のコードを書く必要はありません。
よくある質問
NavigationViewは古いAPI(iOS 13-15)で、宣言的なNavigationLinkのみをサポートします。NavigationStackは新しいAPI(iOS 16+)で、プログラムナビゲーション、ディープリンク、厳密に型付けされたスタックのためのpathを追加します。Appleは新しいプロジェクトにNavigationStackを推奨しています。
.toolbarモディファイアとToolbarItemを使用します。例:.toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button('設定') { } } }。Placementで位置を指定:trailing(右)、leading(左)、principal(中央)。
タイトルは.navigationTitle('タイトル')で設定します。スタイルは.navigationBarTitleDisplayMode(.large)または.inline。LargeはiOS Musicスタイルの大きなタイトル、inlineは設定アプリのようなコンパクトなスタイルです。スタイルは画面ごとに個別に変更できます。
3つの方法:valueを使う(NavigationLink(value:item) { Label }、iOS 16+)、destination + labelを使う、プログラム遷移にisActiveを使う。valueを使ったNavigationLinkは、遷移前にターゲットViewを作成する必要がないため、リストでよりクリーンです。
はい。NavigationViewとNavigationStackはiOS、iPadOS、watchOS、tvOS、macOSで利用可能です。watchOSではDigital Crownを使ったインターフェース階層によるナビゲーション、tvOSではリモコンを使ったフォーカスベースの入力です。動作はプラットフォームに自動的に適応します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。