
シートUIを半透明やマテリアル背景で表示すると、後ろの画面がうっすら見えますよね。
では、その“見えている背面”はタップできるべきか、できないべきか?
この「背面コンテンツにタップやスクロールを通すかどうか」を決められるのが .presentationBackgroundInteraction(_:)
です。
.sheet
と組み合わせることで、シートのモーダル度(どれだけ前面ビューに集中させるか)をコントロールできます。
.presentationBackgroundInteraction(_:)とは?
.presentationBackgroundInteraction(_:)
は、シート表示中に背面ビューへのユーザー操作を許可するかを指定できるSwiftUIの修飾子です。
主に以下の3つのモードがあります。
.enabled
背面へのタップやスクロールを許可します。軽めの情報表示やツールなど、背面を触りながら使う想定に向いています。.disabled
背面への操作を遮断します。入力や決済など、ユーザーに前面シートへ集中してもらいたいときに使います。.upThrough(<Detent>)
指定したデテント以下の高さでは背面操作を許可し、それ以上では遮断します。
この機能は iOS 16以降 で使えます。
.presentationDetents
や .presentationBackground(_:)
と組み合わせると、高さ・見た目・操作可否をまとめてデザインできます。
どういう時に使うのが便利?
- 軽量シートの補助UI
例:ミニプレイヤーや検索フィルタ。背面を操作しながら使えると便利。 - プレビュー/ピッカー
背面リストをスクロールしつつ、条件だけ前面で切り替える。 - 段階的モーダル
小さい高さのときは背面操作OK、全画面に近づいたら遮断。
基本的な使い方(最小例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
struct ContentView: View { @State private var show = false var body: some View { Button("シートを開く") { show = true } .sheet(isPresented: $show) { SheetView() .presentationDetents([.fraction(0.25), .large]) .presentationBackground(.ultraThinMaterial) // 半透明背景 .presentationBackgroundInteraction(.enabled) // 背面操作を許可 } } } struct SheetView: View { var body: some View { VStack(spacing: 12) { Text("背面を触れる軽量シート") Text("スクロールやタップが背面に届きます") Spacer() } .padding() } } |
モード別の挙動と選び方
繰り返しになりますが、.presentationBackgroundInteraction(_:)
は、モードによって背面への操作が通るかどうかが変わります。
それぞれのモードの性質を理解しておくと、UIの意図に合わせた自然な挙動を設計できます。
.enabled
背面を触りながら使えるシートにしたい場合に選びます。背景が半透明で後ろが見えるときに自然です。.disabled
背面操作を完全に遮断して、前面シートに集中してもらいたい場合に使います。.upThrough(<Detent>)
高さによって自然に挙動を切り替えたいときに便利です。
選ぶポイントは 「見た目(背景の重さ)」と「操作可否」を一致させること です。
デテントと組み合わせた応用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
struct AdaptiveSheet: View { @State private var show = false @State private var detent: PresentationDetent = .fraction(0.3) var body: some View { Button("開く") { show = true } .sheet(isPresented: $show) { VStack { Text("高さで挙動が変わる"); Spacer() } .padding() .presentationDetents([.fraction(0.3), .medium, .large], selection: $detent) .presentationBackground(.ultraThinMaterial) .presentationBackgroundInteraction(.upThrough(.medium)) // medium以下で背面許可 } } } |
.fraction(0.3)
、.medium
、.large
)で切り替えられるようにし、.presentationBackgroundInteraction(.upThrough(.medium))
を指定しています。
その結果、高さが .medium
以下のときは背面のタップやスクロールを許可し、.large
になると背面操作を遮断します。
こうすることで、
- 画面の一部だけを覆う「軽い状態」では背面も触れる
- 画面を広く覆う「重い状態」ではユーザーの意識を前面シートに集中させる
というように、シートの高さに応じた自然な操作感を実現できます。
注意点
まず、この修飾子は .sheet
用であり、fullScreenCover
のように背面が存在しない場合には効果がありません。
また、背面操作を許可するかどうかの設定と、シートを閉じられるかどうかの設定は別です。
閉じ可否を制御したい場合は .interactiveDismissDisabled
を使用します。
さらに、.upThrough
の判定は現在のデテントに依存します。
selection
とデテント候補が一致しないと意図通り動かないことがあるため、設定の整合性に注意が必要です。
最後に、端末の回転やキーボードの表示などで実際の高さが変化することがあります。
そのため、姿勢や画面回転を含めて実機でしっかり検証することが大切です。
まとめ
.presentationBackgroundInteraction(_:)
は、シートのモーダル度を操作面から調整できる重要な修飾子です。
- 軽いUIなら
enabled
- 前面に集中させたいUIなら
disabled
- 段階的に切り替えるなら
upThrough
.presentationBackground(_:)
や .presentationDetents
と組み合わせて、見た目と操作感に一貫性のあるシート体験を作りましょう。
参考リンク
- presentationBackgroundInteraction(_:) | Apple Developer Documentation
- presentationBackground(_:) | Apple Developer Documentation
- presentationDetents(_:selection:) | Apple Developer Documentation
- interactiveDismissDisabled(_:) | Apple Developer Documentation