LoginSignup
2
2

More than 3 years have passed since last update.

【SwiftUI】sheetメソッドを使ってビューをモーダル表示にする

Posted at

先日リリースした私のアプリに使用した技術の解説です。
私のアプリはこちら。

sheetメソッドとは

ビューをモーダル表示させるメソッド。下から出てきて画面の一番手前に表示される。

実際の動作

「わかった!」ボタンを押すと下から答え合わせのビューが出てきて、画面の一番手前に表示されているのがわかるかと思います。
また、このシートは上下に動かすことができ、一定の位置まで下げて指を離すと閉じるようになっています。

基本の書き方

sheetメソッド
.sheet(isPresented: ブール値, content: { 表示させたいビュー })

sheetメソッドはさまざまな引数を取りますが、一番シンプルな書き方はこのようになります。isPresentedがtrueになったとき、contentの{ }内のビューが表示されます。

ソースコード

上のサンプルアプリのコードの一部です。

ContentView.swift
import SwiftUI

struct ContentView: View {

    @State var answer = ""
    @State var moveAnswer = false //シートを出すためのブール型の変数

    var body: some View {
        VStack{
            Text("なぞなぞ")
                .font(.title)
                .padding()
            Text("パンはパンでも白黒のかわいいパンは\nぱ〜んだ?")
            TextField("こたえを書いてね", text: $answer)
                .frame(width: 200)
                .padding()
                .border(Color.black)
            // シートを出すトリガーになるボタン
            Button(action: {
                moveAnswer = true //シートを出すためのアクション
            }, label: {
                Text("わかった!")
                    .padding()
                    .background(Color.green)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            })
            //moveAnswerがtrueになったときに出てくるシート
            .sheet(isPresented: $moveAnswer, content: {
                Answer(answer: answer, moveAnswer: $moveAnswer)
            })
        }
    }
}

こちらのコードを部分ごとにわけて解説したいと思います。

シートを出すための仕組み

まず、ContentViewのプロパティとしてブール型の変数を用意します。

    @State var moveAnswer = false //シートを出すためのブール型の変数

アプリ起動時はシートが出ていない状態にしたいため、初期値にfalseを入れています。逆に言えば、初期値をtrueにすればアプリ起動時にシートを出すことができます。

次は、シートを出すトリガーになるボタンです。

// シートを出すトリガーになるボタン
            Button(action: {
                moveAnswer = true //シートを出すためのアクション
            }, label: {
                Text("わかった!")
                    .padding()
                    .background(Color.green)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            })

ボタンをタップするとmoveAnswerにtrueが代入されます。

そして、sheetメソッドを見ていきます。

            .sheet(isPresented: $moveAnswer, content: {
                Answer(answer: answer, moveAnswer: $moveAnswer)
            })

ボタンのアクションによってmoveAnswerにtrueが入るとisPresentedがtrueになり、contentのAnswerビューが表示されます。

今回、AnswerビューはAnswer.swiftという別のファイルを作って書きました。そちらのビューも見てみましょう。

今回シートに表示したビュー

Answer.swift
import SwiftUI

struct Answer: View {

    let answer: String //前の画面のなぞなぞの答え
    @Binding var moveAnswer: Bool //前の画面のmoveAnswerを反映させるための変数

    var body: some View {
        VStack{
            //なぞなぞの答えが正解かどうかで表示を変える
            if answer == "パンダ" {
                Text("せいかい!!\nすごい!天才だ!")
                    .font(.title)
                Image("correct")

            }else{
                Text("ちがうよ。もういちどもんだいをよく読んでみよう。")
                    .font(.title)
                Image("fault")
            }
            //シートを閉じるためのトリガーになるボタン
            Button(action: {
                moveAnswer = false //シートを閉じるためのアクション
            }, label: {
                Text("もどる")
                    .font(.title)
                    .padding()
            })
        }
    }
}

動画内でもやっていたように、わざわざボタンを作らなくてもシートを閉じる操作はできますが、ボタンがあった方が便利な場面もあるかと思います。このボタンの作り方について解説したいと思います。

シートを閉じるためのボタンの作り方

シートを閉じるためには、ContentViewのmoveAnswerがfalseになる必要があります。そのため、まずはContentViewのmoveAnswerをAnswerビューに反映させます。

   @Binding var moveAnswer: Bool //前の画面のmoveAnswerを反映させるための変数

@Bindingをつけることで、このmoveAnswerに入れたブール値の状態を共有しています。つまり、AnswerのmoveAnswerがfalseになると、ContentViewのmoveAnswerもfalseに変わるようにしています。

そしてこちらがシートを閉じるためのトリガーとなるボタンです。

            //シートを閉じるためのトリガーになるボタン
            Button(action: {
                moveAnswer = false //シートを閉じるためのアクション
            }, label: {
                Text("もどる")
                    .font(.title)
                    .padding()
            })

このボタンを押すことでmoveAnswerにfalseが入り、シートを閉じることができます。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2