SwiftUI - SheetとBindingの使い方

1. SheetとBindingの使い方

alt

ここでは、Sheetと@Bindingの使い方について書いています。SheetはGIF画像のように下から上に上がってくるモーダルビューを表示します。このページでは2つのファイルを使用してモーダルビューを作成しています。ファイルの内容は下記のようになっています。

  1. ContentView.swift - モーダルビューを表示させるボタンを出力
  2. SheetShowView.swift - モーダルビューの中身

はじめに、SheetShowView.swiftを作成して下記のように記述します。ZStack {Color()}で背景色の変更が可能です。セーフティエリアも色を入れたい場合は.edgesIgnoringSafeArea(.all)を追加します。

struct SheetShowView: View {
  var body: some View {
    ZStack {
      Color(red: 0.2, green: 0.4, blue: 0.9, opacity: 1)
      .edgesIgnoringSafeArea(.all)

      Text("Hello, World!")
      .padding()
      .foregroundColor(Color(.white))
    }
  }
}

struct SheetShowView_Previews: PreviewProvider {
  static var previews: some View {
    SheetShowView()
  }
}

上記で作成したファイルを.sheet{...}内に入れることでモーダルビューとして出力してくれます。ここではボタンクリックでモーダルビューの表示非表示をしています。デフォルトスタイルは半モーダルビュー(フルスクリーン表示ではなく上に余白がある)でスワイプで閉じることが可能です。

struct ContentView: View {
  @State var isSheetShow: Bool = false
    
  var body: some View {
    VStack {
      Button(action: {
        isSheetShow.toggle()
      }) {
        Text("Button")
      }
      .frame(width: 100, height: 40)
      .foregroundColor(Color(.white))
      .background(Color(red: 0.2, green: 0.4, blue: 0.9, opacity: 1))
      .cornerRadius(10)
    }
    .sheet(isPresented: $isSheetShow) {
      SheetShowView()
    }
  }
}

isPresented: Bool - ビューが現在表示されているかどうかを示す

2. Bindingを使って閉じるボタンを追加する

BindingStateの値を他のViewと紐付ける(バインディング)ことができるようです。SheetShowViewに下記を追加します。

struct SheetShowView: View {
  @Binding var isSheetShow: Bool //<<追加

  var body: some View {
    ZStack {
      Color(red: 0.2, green: 0.4, blue: 0.9, opacity: 1)
      .edgesIgnoringSafeArea(.all)
      VStack {
        Text("Hello, World!")
        .padding()
        //vv追加
        Button("閉じる",
          action: {isSheetShow.toggle()})
    }.foregroundColor(Color(.white))
  }
}

struct SheetShowView_Previews: PreviewProvider {
  static var previews: some View {
    SheetShowView(isSheetShow: Binding.constant(false)) //<<追加
  }
}

Binding.constant() - 変更できない値でBindingを作成

値を受け取るためにContentViewに下記を追加すれば完了です。

struct ContentView: View {
  ...
    .sheet(isPresented: $isSheetShow) {
      SheetShowView(isSheetShow: $isSheetShow) //追加
    }
  }
}

3. フルスクリーンにしたい場合

モーダルビューをフルスクリーンにしたい場合、下記のように変更するとフルスクリーンになります。.fullScreenCover.sheetと違いスワイプなどはできません。なので閉じるボタンなどフルスクリーンを解除するイベントがないとロック画面にできるという側面もありそうです。

struct ContentView: View {
  ...
    .fullScreenCover(isPresented: $isSheetShow) {
      SheetShowView(isSheetShow: $isSheetShow)
    }
  }
}

sheet | Apple Developer Documentation
Binding | Apple Developer Documentation
constant | Apple Developer Documentation