I'm wondering what the correct, or recommended, way is to dismiss a SwiftUI that is being presented as a sheet hosted by an NSHostingController
. The usual technique of invoking @Environment(\.dismiss)
does not appear to work.
Consider the code below. An NSWindowController
is attempting to display a SwiftUI SettingsView
as a sheet. The sheet is correctly presented, but the SettingsView
is unable to dismiss itself.
I am able to make it work by passing a closure into SettingsView
that calls back to the NSWindowController
but it's rather convoluted because SettingsView
doesn't know the view controller that's hosting it until after SettingsView
has been created, which means "finding" that view controller in the window controller to dismiss is more involved than it should be.
Is there a better strategy to leverage here?
final class MyViewController: NSViewController {
@IBAction func buttonClicked(_ sender: NSButton) {
if let presenter = window?.contentViewController {
presenter.presentAsSheet(NSHostingController(rootView: SettingsView()))
}
}
}
struct SettingsView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
VStack {
Button("Cancel", role: .cancel) {
dismiss() // This call does not dismiss the sheet.
} .keyboardShortcut(.cancelAction)
}
}
}
Thank you.
macOS 15.4.1 (24E263), Xcode 16.3 (16E140)