Navigationを使った画面遷移を学ぼう
これまで第5回では、sheetを用いた画面遷移、第7回ではTabViewを用いたタブでの画面切り替え方法を学びました。今回は、Navigationを使った画面遷移方法を学びます。
Navigation遷移とは、アプリ内で画面を切り替える仕組みです。SwiftUIでは、Navigation遷移の方法の一つとして、NavigationStackを使います。
NavigationStackを使用することで、アプリの画面を積み重ねるように管理でき、画面の遷移や戻る操作を簡単に行えます。
Navigation遷移の方法はいくつかありますが、今回はNavigationStackを画面遷移の土台にし、NavigationLinkで次の画面に遷移する方法を説明します。
次のようにコードを書き換えて動作を確認してみましょう。
struct MyAppListView: View {
var body: some View {
// ここを追加↓
NavigationStack {
List {
// ここを変更↓
NavigationLink("毎日いいことカウンター") {
Text("毎日いいことカウンター")
}
Text("やるのかやらないのかコイントス")
Text("愚っ痴る")
Text("カップラーメンタイマー")
Text("福笑いゲーム")
}
}
}
}
NavigationStackの{}内に作成済みのListを移動させています。NavigationStack内に配置されたViewは、このNavigationStackの最初に表示される画面になります。この画面から他の画面に移動したり、移動先から元の画面に戻ったりできます。
そして、画面遷移を行うためにNavigationLinkを使用しています。NavigationLinkは、画面間のナビゲーションを実現するSwiftUIのViewです。
このリンクをタップすると、指定した遷移先のViewが表示されます。リンクの外観は、文字列を渡す方法や、カスタムしたViewを使用することで、自由に変更することができます。
今回はText("毎日いいことカウンター")の箇所をNavigationLinkに変更しています。
// リンクのラベル↓
NavigationLink("毎日いいことカウンター") {
// 遷移後に表示されるView↓
Text("毎日いいことカウンター")
}
List上でNavigationLinkを使用すると、プレビューのようにラベルの横に>が付いた状態で表示されます。

実際に、毎日いいことカウンターのリンクをタップすると、毎日いいことカウンターというテキストが表示される画面に遷移します。また、画面左上のBackをタップすると最初のListの画面に戻ってきます。

最後に、Text("毎日いいことカウンター")の部分を第3回で作成したGoodCounterView()に差し替えて、毎日いいことカウンターアプリに遷移できるか確認してみます。
struct MyAppListView: View {
var body: some View {
NavigationStack {
List {
NavigationLink("毎日いいことカウンター") {
// ここを変更↓
GoodCounterView()
}
Text("やるのかやらないのかコイントス")
Text("愚っ痴る")
Text("カップラーメンタイマー")
Text("福笑いゲーム")
}
}
}
}
プレビューでList上の毎日いいことカウンターのリンクをタップすると、毎日いいことカウンターアプリを表示することができます。

その他のTextも、「毎日いいことカウンターアプリ」と同じようにNavigaitonLinkに変更します。ぜひ挑戦してみてください。
NavigationLinkに変更すると、次のようになります。
struct MyAppListView: View {
var body: some View {
NavigationStack {
List {
NavigationLink("毎日いいことカウンター") {
GoodCounterView()
}
// ここを変更↓
NavigationLink("やるのかやらないのかコイントス") {
YesNoCoinTossView()
}
// ここを変更↓
NavigationLink("愚っ痴る") {
ComplaintView()
}
// ここを変更↓
NavigationLink("カップラーメンタイマー") {
CupRamenTimerView()
}
// ここを変更↓
NavigationLink("福笑いゲーム") {
LuckyLaughView()
}
}
}
}
}
プレビュー画面でも、それぞれがリンクになります。タップすると作成済みのアプリの画面が表示されるようになりました。

Navigationにタイトルをつける
アプリ内で画面の目的を分かりやすく伝えるために、Navigationにタイトルをつける方法を説明します。Navigationにタイトルをつけるには、.navigationTitleモディファイアを使用します。このモディファイアを次のようにNavigationStackの{}より内側につけてください。
struct MyAppListView: View {
var body: some View {
NavigationStack {
List {
NavigationLink("毎日いいことカウンター") {
GoodCounterView()
}
NavigationLink("やるのかやらないのかコイントス") {
YesNoCoinTossView()
}
NavigationLink("愚っ痴る") {
ComplaintView()
}
NavigationLink("カップラーメンタイマー") {
CupRamenTimerView()
}
NavigationLink("福笑いゲーム") {
LuckyLaughView()
}
}
// ここを追加↓
.navigationTitle("ミニアプリリスト")
}
}
}
プレビューでNavigationにタイトルが付いたことを確認できます。

デフォルトでは大きいタイトルが表示されていますが、リストをスクロールすると小さいタイトルに変化します。

表示されるミニアプリ側にタイトルをつける
Listにはタイトルをつけることができたので、ミニアプリ側にもタイトルをつけます。NavigationLinkの中にある遷移先のViewに対して、navigationTitleモディファイアをつけると、タイトルをつけることができます。
struct MyAppListView: View {
var body: some View {
NavigationStack {
List {
NavigationLink("毎日いいことカウンター") {
GoodCounterView()
// ここを追加↓
.navigationTitle("毎日いいことカウンター")
}
プレビューで毎日いいことカウンターのリンクをタップして遷移すると、タイトルが表示されるのが確認できます。

Navigationのタイトル表示スタイルを変更する
ミニアプリの画面でもタイトルを表示できたら、表示するタイトルの大きさを調整しましょう。タイトル文字の大きさは、.navigationBarTitleDisplayModeモディファイアで、表示スタイルを指定することで変更することができます。
次のようにコードを追加してください。
struct MyAppListView: View {
var body: some View {
NavigationStack {
List {
NavigationLink("毎日いいことカウンター") {
GoodCounterView()
.navigationTitle("毎日いいことカウンター")
// ここを追加↓
.navigationBarTitleDisplayMode(.inline)
}
.navigationBarTitleDisplayModeに、表示したいNavigationBarItem.TitleDisplayModeの値を入力します。NavigationBarItem.TitleDisplayModeには3つのモードがあります。
| 表示モード | 詳細 |
|---|---|
| automatic | タイトルの表示モードを前のNavigationから継承 |
| inline | タイトルをNavigationのバーの標準的な範囲内に表示 |
| large | Navigationのバー内に大きなタイトルを表示 |
今回は.navigationBarTitleDisplayMode(.inline)を追加しているため、標準的なサイズのタイトルが表示されます。
プレビューで実際にリンクをタップして確認すると、標準的なサイズのタイトルが表示されるようになっています。

他も同じようにNavigationLink内のViewに、.navigationTitleと.navigationBarTitleDisplayMode(.inline)を追加します。
struct MyAppListView: View {
var body: some View {
NavigationStack {
List {
NavigationLink("毎日いいことカウンター") {
GoodCounterView()
.navigationTitle("毎日いいことカウンター")
.navigationBarTitleDisplayMode(.inline)
}
NavigationLink("やるのかやらないのかコイントス") {
YesNoCoinTossView()
// ここを追加↓
.navigationTitle("やるのかやらないのかコイントス")
.navigationBarTitleDisplayMode(.inline)
}
NavigationLink("愚っ痴る") {
ComplaintView()
// ここを追加↓
.navigationTitle("愚っ痴る")
.navigationBarTitleDisplayMode(.inline)
}
NavigationLink("カップラーメンタイマー") {
CupRamenTimerView()
// ここを追加↓
.navigationTitle("カップラーメンタイマー")
.navigationBarTitleDisplayMode(.inline)
}
NavigationLink("福笑いゲーム") {
LuckyLaughView()
// ここを追加↓
.navigationTitle("福笑いゲーム")
.navigationBarTitleDisplayMode(.inline)
}
}
.navigationTitle("ミニアプリリスト")
}
}
}
Navigationのタイトルに背景色をつける
各ミニアプリにもタイトルを付けることができたのですが、カップラーメンタイマー画面に遷移してみると、Navigationのタイトルが表示されていないように見えます。

これはデフォルトのNavigationのタイトルが黒色のため、カップラーメンタイマー画面の背景色と被って、見えなくなってしまっているのが原因です。この問題をNavigationのタイトルに背景色を付ける方法で今回は解決していきます。
NavigationLink("カップラーメンタイマー") 内のコードを次のように変更します。
NavigationLink("カップラーメンタイマー") {
CupRamenTimerView()
.navigationTitle("カップラーメンタイマー")
.navigationBarTitleDisplayMode(.inline)
// ここを追加↓
.toolbarBackgroundVisibility(.visible, for: .navigationBar)
.toolbarBackground(.yellow, for: .navigationBar)
}
Navigationバーに背景色を付けるには、toolbarBackgroundモディファイアを使用して、付けた色と箇所を指定します。
また、このNavigationのバーですが、スクロール可能なViewのスクロール状態によって、背景色が表示されたり表示されなかったりする挙動になっています。そのため、ただtoolbarBackgroundで色を指定するだけでは色が反映されない場合があります。
今回もtoolbarBackgroundだけでは反映されないため、toolbarBackgroundVisibilityモディファイアを使用して、Navigationのバーの背景を強制的に見える状態にしています。
プレビューで、カップラーメンタイマーの画面に遷移すると、Navigationのバーに背景色が付いてタイトルも見えるようになりました。

これでリスト部分は完成です。
