Dismiss a SwiftUI View that is contained in a UIHostingController
I found another approach that seems to work well and which feels a little cleaner than some of the other approaches. Steps:
- Add a
dismissAction
property to the SwiftUI view:
struct SettingsUIView: View {
var dismissAction: (() -> Void)
...
}
- Call the
dismissAction
when you want to dismiss the view:
Button(action: dismissAction ) {
Text("Done")
}
- When you present the view, provide it with a dismissal handler:
let settingsView = SettingsUIView(dismissAction: {self.dismiss( animated: true, completion: nil )})
let settingsViewController = UIHostingController(rootView: settingsView )
present( settingsViewController, animated: true )
UPDATE: From the release notes of iOS 15 beta 1:
isPresented, PresentationMode, and the new DismissAction action dismiss a hosting controller presented from UIKit. (52556186)
I ended up finding a much simpler solution than what was offered:
final class SettingsViewController: UIHostingController<SettingsView> {
required init?(coder: NSCoder) {
super.init(coder: coder, rootView: SettingsView())
rootView.dismiss = dismiss
}
func dismiss() {
dismiss(animated: true, completion: nil)
}
}
struct SettingsView: View {
var dismiss: (() -> Void)?
var body: some View {
NavigationView {
Form {
Section {
Button("Dimiss", action: dismiss!)
}
}
.navigationBarTitle("Settings")
}
}
}