navigationTitle と navigationBarTitleDisplayMode

ナビゲーションバーのタイトルは navigationTitle で設定し、navigationBarTitleDisplayMode で表示スタイルを制御します。

navigationTitle の基本

NavigationStack {
    Text("コンテンツ")
        .navigationTitle("ホーム")
}

タイトルは NavigationStack の直下ではなく、その中のビューに対して設定します。

タイトル表示モード

navigationBarTitleDisplayMode でタイトルの表示スタイルを指定できます。

NavigationStack {
    List {
        Text("項目1")
        Text("項目2")
    }
    .navigationTitle("設定")
    .navigationBarTitleDisplayMode(.large)
}
.automatic

コンテキストに応じて自動選択。最初は large、スクロールすると inline に変化することが多い。

.large

大きなタイトルを表示。コンテンツ上部に配置され、スクロールすると縮小する。

.inline

ナビゲーションバー中央に小さく表示。常に同じサイズを維持する。

表示モードの比較

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                NavigationLink("Large モード") {
                    sampleList
                        .navigationTitle("Large")
                        .navigationBarTitleDisplayMode(.large)
                }
                NavigationLink("Inline モード") {
                    sampleList
                        .navigationTitle("Inline")
                        .navigationBarTitleDisplayMode(.inline)
                }
            }
            .navigationTitle("タイトルモード")
        }
    }
    
    var sampleList: some View {
        List(1...20, id: \.self) { i in
            Text("項目 \(i)")
        }
    }
}

動的なタイトル

タイトルは動的に変更することも可能です。

struct CounterView: View {
    @State private var count = 0
    
    var body: some View {
        NavigationStack {
            VStack {
                Text("\(count)")
                    .font(.largeTitle)
                
                Button("カウントアップ") {
                    count += 1
                }
            }
            .navigationTitle("カウント: \(count)")
        }
    }
}

Text を使ったタイトルカスタマイズ

iOS 17 以降では、Text ビューを使ってタイトルをカスタマイズできます。

.navigationTitle(Text("重要").foregroundColor(.red))

ただし、この方法には制限があり、すべてのスタイルが反映されるわけではありません。

ナビゲーションバーの表示/非表示

toolbarnavigationBarHidden でナビゲーションバー自体を非表示にできます。

NavigationStack {
    ContentView()
        .toolbar(.hidden, for: .navigationBar)
}
.large モード

画面上部に大きなタイトル。設定画面やメインメニューに適している。

.inline モード

コンパクトな表示。詳細画面や階層が深い画面に適している。

実践例:階層に応じたタイトルモード

一般的なパターンとして、ルート画面では .large、詳細画面では .inline を使うことが多いです。

struct MainView: View {
    var body: some View {
        NavigationStack {
            List {
                NavigationLink("詳細へ") {
                    DetailView()
                }
            }
            .navigationTitle("メイン")
            .navigationBarTitleDisplayMode(.large)  // ルートは large
        }
    }
}

struct DetailView: View {
    var body: some View {
        Text("詳細コンテンツ")
            .navigationTitle("詳細")
            .navigationBarTitleDisplayMode(.inline)  // 詳細は inline
    }
}

タイトルの表示モードを適切に設定することで、ユーザーにとって分かりやすい階層構造を表現できます。