[SwiftUI]sheetを使ってモーダル画面遷移を実装する

「 SwiftUIアプリでモーダル遷移を実装したい… 」

「 SwiftUIのsheetってどう使えばいいの…? 」

こんばんは、中川です。

今回はSwiftUIのView機能であり、シート画面を実装できる「sheet(シート)」を解説します!

sheet機能を用いることで、以下のようなシート画面が実装できます。

シート画面は、現在位置する画面の上(前)に表示され、ユーザーがシート画面以外の部分をタップしたり、下にスワイプすると、シート画面が閉じるようになっています。

[SwiftUI]sheetを使ってモーダル画面遷移を実装する
sheetのシンプルな実装例

[ 本記事はこんな人におすすめ ]

・SwiftUIを勉強している

・SwiftUIのsheet機能の使い方を知りたい

・SwiftUIでモーダル遷移を実装したい

環境・バージョン

  > Swift 5.7.2

  > Xcode 14.2

  > macOS 13.0 Ventura

サンプルコードの紹介

本記事内で書いたサンプルコードは筆者のGitHubにアップロードしております。

実際どのように書かれているのか確認したりする際に、良ければお使いください。

1. シート画面の基本的な実装手順

では早速sheetを使ってシート画面を実装していきましょう。

大まかな実装の手順は以下です。

① シート画面の表示/非表示を管理する状態変数を作る

② sheetをViewのbody内に配置する

③ ①で作った状態変数をスイッチングするトリガーを用意する

手順1: シート画面の表示/非表示を管理する状態変数を作る

sheetでモーダル遷移によるシート画面表示を実装するには、画面の表示を管理する状態変数が必要です。

状態変数については以下の記事にて詳しく解説しています。

[SwiftUI]データバインディングを学ぶ!@Stateの機能と使い方

以下のようにBool型の状態変数を準備します。名前は「showSheet」としました。

				
					// シート画面の表示を管理する状態変数
    @State var showSheet: Bool = false
				
			
[SwiftUI]sheetを使ってモーダル画面遷移を実装する

手順2: sheetモディファイアをViewのbody内に配置する

次に、シート画面を表示させたい対象Viewのbody内にsheetモディファイアを配置します。

この時に、sheetモディファイアの引数「isPresented:」に状態変数を紐付けます。この紐付けによって、状態変数の更新とシート画面の表示/非表示が連動するようになります。

				
					.sheet(isPresented: $showSheet) { // ⬅︎ 引数isPresentedに状態変数を紐づける
            
            // この中で実装したViewがシート画面に表示される
            
        }
				
			

sheetは以下のようにbody内にモディファイアとして定義されます。

[SwiftUI]sheetを使ってモーダル画面遷移を実装する

手順3: 状態変数の値を更新するトリガーを用意する

最後に状態変数の値を更新するためのトリガーを作りましょう。

今回はButton(ボタン)を使って状態変数の値を更新します。

「toggle()」とすることでBool型プロパティの値を反転させます。

				
					Button("シートモーダル画面を表示") {
            
            // ボタンタップで状態変数の値を切り替える
            showSheet.toggle()
        }
				
			

見通しを良くするため、デフォルトのコードは削除して、ボタンだけを配置しました。

[SwiftUI]sheetを使ってモーダル画面遷移を実装する

これでモーダル遷移の準備は完了です。

あとはsheetモディファイアのクロージャ内に、シート画面上で表示させたいViewデザインを定義すればOKです。

試しにsheetのクロージャ内にTextを入れてみました。

[SwiftUI]sheetを使ってモーダル画面遷移を実装する

この状態でボタンをタップすると、

[SwiftUI]sheetを使ってモーダル画面遷移を実装する

定義したViewデザイン通りのシート画面が表示できていますね!

以上がsheetによるモーダル遷移の基本的な実装手順です。

2. sheetを使った様々な実装例

sheetの基本的な使い方がわかったところで、sheetの多様な形での実装方法をご紹介します。これらをうまく組み合わせることで、複雑なモーダル遷移の実装を可能にします。

実装例1: 複数のシート画面を出し分ける

以下のように同じView内に複数のsheetを配置すれば、同じ画面内で複数のシート画面を出し分けるような実装ができます。

[ コード例 ]

				
					struct MultipleSheetView: View {
    
    // 状態変数をシート画面の数だけ用意
    @State var showSheet1: Bool = false
    @State var showSheet2: Bool = false
    @State var showSheet3: Bool = false
    
    var body: some View {
        
        // シート画面の数だけ状態変数のトリガーを用意
        VStack(spacing: 40) {
            Button("1つ目のシートモーダル画面を表示") {
                showSheet1.toggle()
            }
            Button("2つ目のシートモーダル画面を表示") {
                showSheet2.toggle()
            }
            Button("3つ目のシートモーダル画面を表示") {
                showSheet3.toggle()
            }
        }
        
        // シート画面の数だけsheetモディファイアを用意
        .sheet(isPresented: $showSheet1) {
            ZStack {
                Color.blue
                Text("これは1つ目のシートモーダル画面です")
            }
        }
        .sheet(isPresented: $showSheet2) {
            ZStack {
                Color.green
                Text("これは2つ目のシートモーダル画面でsy")
            }
        }
        .sheet(isPresented: $showSheet3) {
            ZStack {
                Color.red
                Text("これは2つ目のシートモーダル画面です")
            }
        }
        
    } // body
} // View

				
			

(見分けやすいように各シート画面に背景色を付けています)

[SwiftUI]sheetを使ってモーダル画面遷移を実装する
複数のシート画面を出し分ける実装

実装例2: シート画面の中からさらに次のシート画面を呼ぶ

sheetのクロージャ内に定義したView構造体の中に、さらにsheetを配置しておくことで、多階層的なモーダル遷移の実装ができます。

[ コード例 ]

				
					// 多階層的なシートモーダル遷移の実装
struct MultilevelSheetView: View {
    // 一つ目のシート画面表示を管理する状態変数
    @State var firstShowSheet: Bool = false
    
    var body: some View {
        
        Button("1つ目のシートモーダル画面を表示") {
            firstShowSheet.toggle()
        }
        .sheet(isPresented: $firstShowSheet) {
            
            FirstSheetView()
        }
    }
}

// 一つ目のシートモーダル画面
struct FirstSheetView: View {
    
    // 二つ目のシート画面表示を管理する状態変数
    @State var secondShowSheet: Bool = false
    
    var body: some View {
        Button("2つ目のシートモーダル画面を表示") {
            secondShowSheet.toggle()
        }
        .sheet(isPresented: $secondShowSheet) {
            SecondSheetView()
        }
    }
}

// 二つ目のシートモーダル画面
struct SecondSheetView: View {
    var body: some View {
        Text("これは2つ目のシートモーダル画面です")
    }
}

				
			
[SwiftUI]sheetを使ってモーダル画面遷移を実装する

実装例3: シート画面の表示管理変数を間接的にトリガーする

ここまでの解説では、ボタンアクションによる直接的な状態変数の更新によってシート画面表示を管理してきましたが、間接的な状態変数の更新によるシート画面の表示管理ができると、モーダル遷移実装の幅は大きく広がります。

例えば「カウントが10以上になったらシート画面を表示する」とする場合、以下のように実装できます。

[ コード例 ]

				
					struct CountShowSheetView: View {
    
    @State var count: Int = 0
    @State var showSheet: Bool = false
    
    var body: some View {
        
        Text("\(count)")
            .font(.largeTitle)
        
        Button("値をプラス1する") {
            count += 1
            
            // 条件に当てはまるとシート画面を表示する
            if count >= 10 {
                showSheet.toggle()
            }
        }
        
        .sheet(isPresented: $showSheet) {
            Text("カウントが10になりました!")
        }
    }
}
				
			

ボタンアクション内にif文の条件式を追加して、条件に当てはまったら状態変数を更新します。

このように、異なる変数値の変化を用いて間接的にシート表示を発火させることができます。

[SwiftUI]sheetを使ってモーダル画面遷移を実装する

まとめ

以上、SwiftUIのsheetについて解説しました!

sheet機能の要点をまとめておきましょう。

・状態変数の更新と紐付けてシート画面の表示/非表示を管理する

・シート画面を表示させたいVeiwのbody内にモディファイアとして配置する

・sheetモディファイアのクロージャ内で遷移先のシート画面デザインを定義する

ぜひ、sheetを使いこなしてアプリ開発に役立てていただければと思います👍

\  SHARE  /

Twitter
Facebook
Email

✏️ アプリ開発が学べる勉強会を開催中! 

CodeCandyではアプリ開発を学ぶための勉強会を定期開催しています。
学習する習慣を身につけたい、他の参加者と作業したい、アプリ開発の基本をマスターしたい、という方のために無料で学べる勉強会です。
グループにメンバー登録して頂くと、イベント開催時にメールで通知されます。

▶️グループのメンバーとして参加する

徹底した基礎学習からマスターするiPhoneアプリ開発集中オンライン講座開講!

本書「iPhoneアプリ開発集中講座」を執筆している現役エンジニア講師陣が直接に指導!
基礎、課題実習で実践力を鍛えて、オリジナルアプリ公開までチャレンジ!
充実した転職支援もあるので、エンジニアへ転職したい人にもおすすめです!

まずは、現役エンジニアに相談できる無料相談をご利用ください。

\ Official /

By 中川 賢亮

2022年2月よりSwift学習を始め、4月からiOSアプリ開発オンラインスクール「CodeCandy」にてアプリ開発を学ぶ。 2023年10月に個人開発アプリ「unico」をリリース。現在はアプリの機能アップデートをしながら、スクール運営の技術ブログの執筆や、出版書籍の入稿チェック・デバッグにも携わる。