【Swift UI】NavigationLinkの使い方!navigationDestinationとの組み合わせ

【Swift UI】NavigationLinkの使い方!navigationDestinationとの組み合わせ

この記事からわかること

  • SwiftUINavigationLinkとは?
  • 画面遷移実装する方法
  • 複数あるイニシャライザの使い方

index

[open]

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

みんなの誕生日

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

posted withアプリーチ

SwiftUIでビューをスタック構造で管理するためのNavigationStackにおいて画面遷移に欠かせないNavigationLinkの使い方をまとめていきます。

NavigationLink構造体とは?

公式リファレンス:NavigationLink構造体

struct NavigationLink<Label, Destination> where Label : View, Destination : View

NavigationLinkナビゲーションプレゼンテーションを制御する機能を提供する構造体です。ユーザーがボタンやテキストなどをタップした際に任意の画面に遷移させることができます。遷移機能を有効にするためにはNavigationStackで囲われている必要があります。

インスタンス化時の引数として必要になるのはリンクの文字となるLabel遷移先を示すViewです。

使い方

実際の使い方を見てみます。最初の引数にString型を渡し、クロージャーの中に遷移先のビューを渡します。

NavigationLink("MyNextView") {
    MyNextView()
}

これでボタンをクリックすると画面が遷移するリンクボタンを作成できます。

【Swift UI】NavigationLinkの使い方!navigationDestinationとの組み合わせ

複数あるイニシャライザ

イニシャライザが複数用意されているので書式が様々あります。

NavigationLink {
    MyNextView()
} label: {
    Label("MyNextView", systemImage: "folder")
}
【Swift UI】NavigationLinkの使い方!navigationDestinationとの組み合わせ

変数の値に応じて画面遷移を動作させる

リンクボタンではなく、変数の値の変化に応じて画面遷移を動作させるにはinit(_:destination:isActive:)を使用します。

struct TestNavigationView: View {
    @State  var isActive:Bool = false
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: MyNextView(),
                               isActive: $isActive,
                               label: { EmptyView() })
                
                Button {
                    isActive = true
                } label: {
                    Text("Navigate Button")
                }
            }
            .navigationTitle("Navigation")
        }
    }
}
struct MyNextView: View {
    var body: some View {
        Text("MyNextView")
    }
}

ですがiOS13〜16以降では非推奨となっているのでnavigationDestinationへの置き換えが推奨されています。

struct TestNavigationView: View {
    @State  var isPresented:Bool = false
    var body: some View {
        NavigationStack {
            Button {
                isPresented = true
            } label: {
                Text("MyNextView")
            }.navigationDestination(isPresented: $isPresented) {
                MyNextView()
            }
        }
    }
}

遷移先ごとに渡す値を変化させる

navigationDestinationinit(_:value:)を使用することで遷移先ごとに渡す値を変化させることができます。

struct TestNavigationView: View {
    
    var body: some View {
        NavigationStack {
            List {
                NavigationLink("Mint", value: Color.mint)
                NavigationLink("Pink", value: Color.pink)
                NavigationLink("Teal", value: Color.teal)
            }
            .navigationDestination(for: Color.self) { color in
                ColorDetail(color: color)
            }
            .navigationTitle("Colors")
        }
    }
}

struct ColorDetail: View {
    var color:Color
    var body: some View {
        Text("ThisColor")
            .foregroundColor(color)
    }
}

この場合はnavigationDestination(for:)を使用することでクリックされたNavigationLinkの値を受け取ることができます。そのためにはforの引数には受け取るデータ型を明示的に指定する必要があります。

func navigationDestination<D, C>(for data: D.Type, @ViewBuilder  destination: @escaping (D) -> C) -> some View where D : Hashable, C : View

公式リファレンス:navigationDestination(for:)

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

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

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

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

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

searchbox

スポンサー

ProFile

ame

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

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

New Article

index