SwiftUI入門-勉強メモ006-【基本的な画面遷移】

SwiftUIでの画面遷移は,

NavigationViewとNavigationLink

で行います.

Viewの上にこれらのコントロール(UI部品)を配置してアプリを作成していきます. 今回は基本部品の一つTextFieldです.

環境は,

  • macOS Catalina 10.15.7
  • Xcode 12.0.1
  • Swift 5.3
  • iOS 14.0

です.

目次

1つのファイルで画面遷移を行う

SwiftUI
SwiftUI

実際のコードは次のようになります.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView{
            NavigationLink(destination: SubView()) {
                Text("画面遷移")
                    .font(.largeTitle)
            }
        }
    }
}

struct SubView: View {
    var body: some View {
        Text("移動しました!")
            .font(.largeTitle)
            .foregroundColor(Color.pink)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

詳しく見ていきましょう.

SwiftUI
  1. が最初の画面の実装
  2. 移動した先の画面の実装

をしています. 最後の

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

はプレビュー表示をしています. したがって, 画面遷移自体は❶と❷で実装されています.

その中核をなすのが,

NavigationView画面遷移を行うことができるコンテナ.
NavigationLink画面遷移の実行を行う「トリガー」の役割を果たす.
ここで行き先を指定することができる.

です. NavigationViewはコンテナの役割も果たすので,

struct ContentView: View {
    var body: some View {
        NavigationView{
            Text("画面遷移")
                .font(.largeTitle)
        }
    }
}

でもエラーは出ません. コードを実行すると, 「画面遷移」というテキストが出るだけで, そこから他の画面に飛ぶことはできません. この中でトリガーの役割をするNavigationLinkを入れて初めて画面遷移が可能となります.

もちろん, NavigationViewを削除して, NavigationLinkだけでも画面遷移はできません. この2つはセットで初めて機能します.

画面遷移を実装した時点で

SwiftUI

も作成されるのもスゴイですね. このあたりはFlutterと同じです.

画面遷移における値の引き渡し【基本編】

次のブログで@State@Bindingについては説明しようと思っていますので, ここでは省きます. これらを使うと基本的な値の受け渡しは可能になります.

SwiftUI
SwiftUI
import SwiftUI

struct ContentView: View {
    
    @State private var word = "画面遷移したよ!"
    
    var body: some View {
        NavigationView{
            NavigationLink(destination: SubView(word: $word)) {
                Text("画面遷移")
                    .font(.largeTitle)
            }
        }
    }
}

struct SubView: View {
    
    @Binding var word: String
    
    var body: some View {
        Text(word)
            .font(.largeTitle)
            .foregroundColor(Color.pink)
    }
}

値はSubViewのイニシャライザで渡します.

画面遷移における入力した値の引き渡し【基本編】

次の例はTextFieldに入れたテキストを次の画面に引き渡すものです.

import SwiftUI

struct ContentView: View {
    
    @State private var name = ""
    
    var body: some View {
        NavigationView{
            VStack(spacing: 30.0) {
                TextField("名前を入れてください。", text: $name)
                    .border(Color.blue, width: 2)
                    .font(.title)
                    .padding(.horizontal, 20.0)
                NavigationLink(destination: SubView(name: $name)) {
                    Text("画面遷移")
                        .font(.title)
                }
                .navigationTitle("最初の画面")
            }
        }
    }
}

struct SubView: View {
    
    @Binding var name: String
    
    var body: some View {
        Text("初めまして, \(name)さん")
            .font(.largeTitle)
            .foregroundColor(Color.pink)
    }
}
SwiftUI
SwiftUI

複数回の画面遷移

最初の画面→2番目の画面→最後の画面と移動します.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView{
            NavigationLink(destination: SubView1()) {
                Text("画面遷移")
                    .font(.largeTitle)
            }
            .navigationTitle("最初の画面")
        }
    }
}

//SubView1
struct SubView1: View {
    var body: some View {
        VStack(spacing: 30.0) {
            Text("SubView1移動しました!")
                .font(.largeTitle)
                .foregroundColor(Color.pink)
            NavigationLink(destination: SubView2()) {
                Text("画面遷移")
                    .font(.largeTitle)
            }
            .navigationTitle("2番目の画面")
        }
    }
}

//SubView2
struct SubView2: View {
    var body: some View {
        Text("SubView2に移動しました!")
            .font(.largeTitle)
            .foregroundColor(Color.green)
    }
}
SwiftUI
SwiftUI
SwiftUI

Viewの階層をまたいでの値の受け渡しは, @Stateを用いてもできなくはありません. ただ, その都度@Bindingで受け取る必要があり, 実用的ではありません. この場合はEnvironmentObjectなどを用いると簡単に受け渡しをすることができます.

次回以降は, プロパティラッパーについてまとめたいと思います.

コメント

コメントする

目次
閉じる