Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

The @Environment(\.dismiss) value in SwiftUI for macOS does not dismiss a sheet presented by an NSWindowController.

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)

The @Environment(\.dismiss) value in SwiftUI for macOS does not dismiss a sheet presented by an NSWindowController.
 
 
Q