Given the following minimal reproducible example:
struct ParentView: View {
@State private var showSheet = false
var body: some View {
return Button("Show sheet") {
showSheet.toggle()
}.sheet(
isPresented: $showSheet,
onDismiss: {
print("Parent onDismiss")
},
content: {
NavigationView {
SheetView(parentShowSheet: $showSheet)
}
}
)
}
}
struct SheetView: View {
@Environment(\.dismiss) private var dismiss
@Environment(\.isPresented) private var isPresented
@Binding var parentShowSheet: Bool
var body: some View {
Button("Manual close") {
dismiss()
}
.onChange(of: isPresented) { isPresented in
print("Sheet isPresented", isPresented)
}
.onChange(of: parentShowSheet) { parentShowSheet in
print("Sheet parentShowSheet", parentShowSheet)
}
}
}
The SheetView's onChange methods are not triggering in the way I would expect. In this example there are two ways to close a sheet once it's opened :
- Click the "Manual close" button which triggers
dismiss(), or - Pull down the sheet to trigger an "interactive close" (the thing that is disabled when
.interactiveDismissDisabled(true)is added to the view).
If you try these both out you'll see that for (1) you'll get two print statements "Sheet parentShowSheet" and "Parent onDismiss", while for (2) you'll just get one print statement "Parent onDimiss".
Three questions:
- Why does "Sheet parentShowSheet" not print in case (2)?
- Why does "Sheet isPresented" not print in either case? I'd think that dismissing a sheet is very literally changing it's
Environment(\.isPresented)value. - How can I add a hook inside of the
SheetViewthat triggers when it is dismissed with either method (1) or method (2) (e.g. something that operates like either of my onChange methods, but actually works in both cases)?