バッテラのハローワールド研究室

エンジニア、プログラミングに関する情報を掲載中!

【SwiftUI】sheetによるモーダル画面遷移方法

SwiftUI

はじめに

今日はSwitUIの勉強していきます。

アプリを作る上で欠かせないと思うのが画面遷移です。

今回はsheetという機能を使った画面遷移について共有したいと思います。

環境

この記事の情報は次のバージョンで動作確認しています。

* MacOS Monterey (12.1)
* Xcode (13.3.1)

モーダルで画面遷移する

まず遷移前画面にて @State Boolな変数を1個作ります。

この変数をオン・オフして画面の表示切り替えをします。

// FirstView
@State private var isShow: Bool = false // 変数名はなんでもいい

画面を表示したいタイミングでisShow(自分がつけた変数名)toggle()とします

// FirstView

 Button(action: { // ボタンなどのイベント処理の中で呼び出します
    self.isShow.toggle()
})

次画面を表示するにはsheetモディファイアを使います。

// FirstView

.sheet(isPresented: $isShow) { // ①
   SecondView(isShow: $isShow) // ②
}

① isPresentedの引数には$をつけた変数名を指定します

.sheetの中で遷移先のViewを作ります

理由は後述しますがSecondViewの引数に$isShowを渡します。

.sheettoggle()をしたViewではなくてもいいです。

これで遷移するようになりました。

全体のコードだとこんな感じになります。

import SwiftUI

struct FirstView: View {
    
    @State var isShow: Bool = false
    
    init() {
        
    }
    
    var body: some View {
        VStack {
            Button {
                isShow.toggle()
            } label: {
                 Text("画面遷移")
            }
            .sheet(isPresented: $isShow) {
                SecondView(isShow: $isShow)
            }
        }
    }
}

コードで前の画面に戻る方法

sheetで呼びしたViewは下にスワイプすれば前の画面に戻れます。

とはいえなんらかの処理をした後に自動で閉じてほしい時もあると思うので、コードで戻る方法を解説します。

遷移前の画面からイニシャライザでもらったisShowを使います。(そのために渡してました)

この変数は書き換える前提で使うため@Bindingの変数にしておく必要があります

// SecondView

@Binding var isShow: Bool

あとは戻りたいタイミングでtoggle()とすれば画面が閉じてくれます。

Button {
    isShow.toggle() 
} label: {
    Text("戻ります")}

@Environmentで戻る方法 (iOS15で可)

参考書などでは@Environment(\.dismiss)を使うやり方が紹介されております。

ただし@EnvironmentiOS15以上の機能になるので注意が必要です!

dismissを使うともっと簡単に戻る処理が書くことができます。

// SecondView

/* @Binding var isShow: Bool これはいらない */

@Environment(\.dismiss) var dismiss

SomeView()
   Button(action: {                                        
       dismiss() // これだけ
   })

dismissは初期化も不要なので遷移前の画面から引数も入りません。使う時もdismiss()だけでいいのですごく楽ちんです。

dismissを使った場合の遷移前の実装も一応載せておきます。ほぼ一緒ですがSecondViewに渡していたフラグがなくなっています。

 // FirstView

 Button(action: {
    self.isShow .toggle()
})
.sheet(isPresented: $isShow) { 
   SecondView()  // 引数がなくなってる
}

おわりに

最後まで見ていただきヘペトナス!

読者登録・Twitterのフォローもお願いします。