【SwiftUI】NavigationViewの使い方!戻るボタンの自作方法

この記事からわかること

  • Swift UINavigationViewとは?
  • 書式使い方メリット
  • iOSアプリ開発での画面遷移実装方法
  • タイトルを付与するには?
  • 「Back」ボタン非表示にする
  • 戻るボタン自作する方法
  • ナビゲーションバー文字色を変更する方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

Swift UIで簡単に画面遷移を実装できる「NavigationView」の使い方についてまとめていきたいと思います。

NavigationViewとは?

NavigationViewSwift UIのView構造体の1つで、階層的なページに対して簡単に画面遷移を実装することができます。

またNavigationView囲っている中の要素のデザインも自動で変更してくれます。ListやPickerなどをよりiPhoneらしく、使い勝手の良い仕様に変えてくれるのもメリットの1つです。

公式リファレンス:NavigationView

しかしiOS13.0〜16.0はDeprecated(非推奨)になっていました。使用する際はご注意ください。

iOS16.0以降はNavigationStackまたはNavigationSplitViewの置き換えが推奨されています。

基本的な使い方

使い方はNavigationView{}で要素を囲むだけです。中に設定する要素をListで囲うことで見た目もiPhoneの設定画面のような仕様に変更してくれます。

struct ContentView: View { 
  var body: some View { 
    NavigationView { 
          List { 
            Text("要素1")
            Text("要素2")
            Text("要素3")
          }
      }
  } 
}
【SwiftUI】NavigationViewの使い方!基本的な使い方

画面遷移させる

NavigationViewの醍醐味である画面遷移を実装するにはNavigationView{}で囲んだ中でNavigationLinkを使用して遷移先を指定します。NavigationLinkはナビゲーションリンクを生成し、実際の画面遷移を実装するView構造体です。

おすすめ記事:【Swift UI】NavigationLinkの使い方!navigationDestinationとの組み合わせ

実装のポイント

struct ContentView: View {
    var body: some View {
        NavigationView {
            
            NavigationLink {
                // 遷移先のビューを指定
                ChildView()
            } label: {
                // リンクボタンのテキストを指定
                Label("ChildViewへ", systemImage: "arrowshape.turn.up.right.fill")
            }
            
        }
    }
}

NavigationLinkイニシャライザは色々あります。他のイニシャライザでは引数destinationに遷移先を指定します。

別のイニシャライザ

init(
    destination: () -> Destination,
    label: () -> Label
)

画面遷移させるリンクをクリックすると実際に画面が切り替わります。前の画面に戻るには左上に自動で実装される「Back」ボタンを押します。この文字は後述しているタイトルを付与することで自動で変更されます。

タイトルを付与する

NavigationView内に指定している要素にタイトルを付与するには、navigationTitleモディファイアを使用します。このモディファイアはNavigationViewではなく中の要素に対して付与するしないと機能しないので注意してください。

実装のポイント

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                Text("要素1")
                Text("要素2")
                NavigationLink("リンク1") {
                    ChildView()
                }
            } .navigationTitle("タイトル")
        }
    }
}
【SwiftUI】NavigationViewの使い方!タイトルを付与する

またタイトルを付与したことで遷移後の画面の「Back」ボタンも「タイトル」ボタンへと変更されます。

ナビゲーションバー(タイトル)を非表示にする

「Back」ボタンの文字を変えるためにタイトルは指定したいけど表示させたくない場合はタイトルのあるナビゲーションバーをnavigationBarHiddenモディファイアを使って非表示にすることで解決できます。

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                Text("要素1")
                Text("要素2")
                NavigationLink("リンク1") {
                    ChildView()
                }
            } .navigationTitle("タイトル")
              .navigationBarHidden(true)
        }
    }
}

toolbar(_:for:)で非表示にする

navigationBarHiddenモディファイアはiOS16以降非推奨になったのでナビゲーションバーを非表示するにはtoolbar(_:for:)モディファイアを使用します。

.toolbar(.hidden, for: .navigationBar)

「Back」ボタンを非表示にする

ナビゲーションバーにデフォルトで表示される「Back」ボタンを表示させたくない場合は子View側にnavigationBarBackButtonHiddenモディファイアを使えば非表示にすることができます。

struct ChildView: View {
    var body: some View {
        Text("ChildView")
    }.navigationBarBackButtonHidden(true)
    
}

上部にツールバーを実装する

NavigationViewにはタイトルだけでなく上部にボタンなどを配置するツールバーを実装できます。toolbarモディファイアをnavigationTitleと同じく中の要素に指定しToolbarItem構造体を使用して実装します。

実装のポイント

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                Text("要素1")
                Text("要素2")
                NavigationLink("リンク1") {
                    ChildView()
                }
            } .navigationTitle("タイトル")
                .toolbar {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button(action: {
                            print("設定ボタンです")
                        }) {
                            Image(systemName: "gearshape.fill")
                        }
                    }
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button(action: {
                            print("マイページです")
                        }){
                            HStack {
                                Image(systemName: "person.fill")
                            }
                        }
                    }
                }
            
        }
    }
}
【SwiftUI】NavigationViewの使い方!上部にツールバーを実装する

toolbarモディファイアの中にはToolBarItem構造体を指定し、その中にボタンを設置します。引数placementには要素の揃え位置を指定します。

リンクの有効/無効を切り替える

リンクボタンは有効/無効を切り替えることもできます。無効にするにはNavigationLink構造体にたいしてdisabled(true)を指定します。

実装のポイント

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                Text("要素1")
                Text("要素2")
                NavigationLink("リンク1") {
                    ChildView()
                }.disabled(true) // 無効にする
            } .navigationTitle("タイトル")
        }
    }
}

戻るボタンを実装する

遷移後の画面から戻るためのボタンはデフォルトで用意されていますが、戻るボタンを自力で実装することも可能です。例えばButtonのアクションに戻る機能を実装してみます。こちらは遷移後側のビューに作成します。

実装のポイント

struct ChildView: View {
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        
        Button(action: {
            dismiss()
        }, label: {
            Text("戻るボタン")
        })
    }
    
}

詳細は以下の記事を参考にしてください。

Pickerをナビゲーションリンクで開く

Pickerのアイテム選択画面をリンクで開かさせるにはPickerNavigationView構造体とForm構造体で囲みます。どうやらPicker自体がナビゲーションの機能を使用しているらしく、ラップしないと正常に動作しないようです(どこかで見ましたがソースに辿り着けず…)。

実装のポイント

struct ContentView: View {
    @State  var selectedLang = 0
    let lang = ["HTML", "CSS", "PHP", "Swift", "C"]
    
    var body: some View {
        NavigationView{
            Form{
                Picker(selection: $selectedLang, label: Text("言語")) {
                    ForEach(lang.indices, id:\.self) { index in
                        Text(lang[index])
                    }
                }
                
            }
        }
    }
}

Pickerを囲むとデザインが以下のようなiPhoneの設定画面のような見た目に自動で切り替わります。

SwiftUIでPickerをナビゲーションリンクで開く

戻るボタンの文字色を変更する

戻るボタンの文字色はデフォルトでは青色ですが、構造体のイニシャライザから変更することもできます。

 init() {
        UINavigationBar.appearance().tintColor = UIColor.orange
    }

カラーに指定できるのはSwift UIのColor型ではないので注意してください。

struct ContentView: View {
    init() {
        UINavigationBar.appearance().tintColor = UIColor.orange
    }
    
    var body: some View {
        NavigationView {
            List {
                Text("要素1")
                Text("要素2")
                NavigationLink("リンク1") {
                    ChildView()
                }
            } .navigationTitle("タイトル")
        }
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

私がSwift UI学習に使用した参考書

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index