この記事は何?
SwiftUIアプリのシートやポップオーバー表示を取り消す方法について、Appleの開発者向けドキュメントを独自に解説する。
Swiftを基礎から学ぶには
自著、工学社より発売中の「まるごと分かるSwiftプログラミング」をお勧めします。変数、関数、フロー制御構文、データ構造はもちろん、構造体からクロージャ、エクステンション、プロトコル、クロージャまでを基礎からわかりやすく解説しています。
dismissプロパティ
Dismiss
環境値を使用して、特定の環境
に対してこの構造体のインスタンスを取得する。
次に、インスタンスを呼び出すと、表示の取り消しを実行する。
インスタンスを呼び出すときにSwiftが呼び出すcallAsFunction()
メソッドを定義するため、インスタンスを直接呼び出す。
このアクションを使用して、次のことができる。
- シートやポップオーバーなどのモーダル表示を取り消す
-
NavigationStack
から現在のビューをポップする -
WindowGroup
またはWindow
で作成したウィンドウを閉じる
アクションの具体的な動作は、どこから呼び出すかによって異なる。
たとえば、シートとして機能するビュー内でDismissAction
を呼び出すボタンを作成できる。
// モーダル表示されるシート
private struct SheetContents: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
Button("Done") {
dismiss()
}
}
}
SheetContents
ビューを表示すると、シートのボタンをタップしてシートを閉じることができる。
// 通常の画面
private struct DetailView: View {
// 「シートが表示されているかどうか」を追跡する状態プロパティ
@State private var isSheetPresented = false
var body: some View {
// ボタンをタップすると、シートがモーダル表示される
Button("Show Sheet") {
isSheetPresented = true
}
.sheet(isPresented: $isSheetPresented) {
SheetContents()
}
}
}
注意すべき点
アクションが適切な環境で定義されているかを確認する。
たとえば、上例のDetailView
ビューでdismiss
プロパティを作成することは適切ではない。
そのようにして、dismiss()
アクションを.sheet(item:onDismiss:content:)
修飾子のコンテンツクロージャから呼び出しても、シートを正しく却下できない。
private struct DetailView: View {
@State private var isSheetPresented = false
@Environment(\.dismiss) private var dismiss // Applies to DetailView.
var body: some View {
Button("Show Sheet") {
isSheetPresented = true
}
.sheet(isPresented: $isSheetPresented) {
// .sheetモディファイア内でdismissアクションを呼び出さないこと
Button("Done") {
dismiss() // Fails to dismiss the sheet.
}
}
}
}
アクションは「それを宣言した環境」に適用される。
つまり、先の方法では、アクションが「sheetContents
の環境」ではなく「DetailView
ビューの環境」に適用されてしまったので、シート表示が取り消されない。
実際に、このDetailView
ビューがルートビューだった場合、macOSとiPadOSのdismiss()
アクションはウィンドウを閉じる。
dismiss()
アクションは「表示中でないビュー」に影響しない。
SwiftUIが「ビューを表示しているかどうか」を照会したい場合は、isPresented
環境値を利用する。
isPresentedプロパティ
「環境に関連付けられたビュー」が表示中かどうか、を示す真偽値。
var isPresented: Bool { get }
この環境値を読み取るには、@Environment
プロパティラッパーを使用してプロパティを作成する。
@Environment(\.isPresented) private var isPresented
SwiftUIが「そのビューをいつ表示するか」を知りたい場合は、他の環境値を利用する。
たとえば、.onChange(of:perform:)
修飾子を使用して、SwiftUIがビューを表示したときにアクションを実行する。
.onChange(of: isPresented) { isPresented in
if isPresented {
// Do something when first presented.
}
}
この.onChange(of:perform:)
は、すでにナビゲーション階層にあるビューに戻るときなど、SwiftUIが特定のプレゼンテーションに対して複数回呼び出せる.onAppear(perform:)
とは動作が異なる。
表示中のビューを取り消すには、dismiss
アクションを使用すること。