💁♂️
【SwiftUI】dismiss()はシートやポップオーバーなどの現在の表示を却下する
はじめに
主張
-
dismiss()は以下のシーンで表示を却下できる-
.sheetや.confirmationDialog,.popoverのようなモーダル -
NavigationStackにおける現在のView
-
-
dismiss()はdismissするViewで環境値を設定しなければならない
本題
dismiss()で.sheet,.confirmationDialog,.popoverのようなモーダル表示を閉じる
ここでは、.sheetを例にdismiss()を使用する。
ParentViewのボタンからシートを呼び出し、ChildViewのボタンでシートを閉じる。
ParentView
import SwiftUI
struct ParentView: View {
@State private var showSheet: Bool = false
var body: some View {
Button("シートを表示") {
showSheet.toggle()
}
.sheet(isPresented: $showSheet) {
ChildView()
}
}
}
ChildView
import SwiftUI
struct ChildView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
Button("閉じる") {
dismiss()
}
}
}

dismiss()を使ってNavigationStack上で現在の表示から前の画面に戻る
ParentView
import SwiftUI
struct ParentView: View {
var body: some View {
NavigationStack {
List {
NavigationLink("ChildViewへ") {
ChildView()
}
}
.navigationTitle("ParentView")
}
}
}
ChildView
import SwiftUI
struct ChildView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
Button("閉じる") {
dismiss()
}
.navigationTitle("ChildView")
}
}

dismiss()はdismissするViewで環境値を設定しなければならない
以下のコードでは正しくシートを閉じることができません。
import SwiftUI
struct ParentView: View {
@Environment(\.dismiss) private var dismiss
@State private var showSheet: Bool = false
var body: some View {
Button("シートを表示") {
showSheet.toggle()
}
.sheet(isPresented: $showSheet) {
ZStack {
Color.yellow
Button("閉じる") {
dismiss()
}
}
}
}
}

上記のコードでは、ParentViewに環境値dismissが設定されていることになり、dismissしたいViewではありません。
なので、前のセクションのように、Viewを分けて正しいViewで環境値dismissを設定する必要があります。
まとめ
-
dismiss()は以下のシーンで表示を却下できる-
.sheetや.confirmationDialog,.popoverのようなモーダル -
NavigationStackにおける現在のView
-
-
dismiss()はdismissするViewで環境値を設定しなければならない
Discussion