ModalPresentationView
Takes the boilerplate out of managing modal presentations in SwiftUI.
Background
SwiftUI currently provides two different ways to manage modal presentations:
The simplest, PresentationButton
, accepts a
Destination
parameter and presents it over the current context. It doesn’t
provide a control for manual dismissal, instead appearing to rely on the
interactive dismissal gesture that’s part of the new default .pageSheet
modal presentation style.
Alternatively, the more powerful presentation(_:)
modifier
allows you to take control of the presentation state yourself, by accepting an
optional parameter of type Modal
.
ModalPresentationView
sits in the middle, providing a
ModalPresentationButton
control with the same API as PresentationButton
,
but additionally:
Unlike the presentation(_:)
modifier, automatically manages the state of
the modal via a new ModalNavigationView
. If you’re familiar with
NavigationView
, then you already know how to use it.
Provides for manual dismissal via ModalDismissButton
, in addition to the
existing interactive dismiss gesture.
Demo

Example code
import ModalPresentationView
import SwiftUI
struct App: View {
var body: some View {
ModalPresentationView {
ModalPresentationButton(destination: DetailScreen()) {
Text("Present")
}
}
}
}
struct DetailScreen: View {
var body: some View {
ModalDismissButton {
Text("Dismiss")
}
}
}
Installation
- In Xcode, open your project and navigate to File > Swift Packages > Add Package Dependency…
- Paste the repository URL and follow the prompts to add the library to your project.
How does it work?
Internally, ModalPresentationView
defines two custom environment keys, which
it then uses to communicate between the container and the buttons, regardless
of where they’re placed in your view hierarchy.
Firstly, ModalPresentationView
injects a present(_:)
closure into the
environment using the .modalPresentAction
key.
When tapped, ModalPresentationButton
reads the closure from the environment
and calls it to notify ModalPresentationView
to trigger a presentation. The
presentation button passes the destination view into the closure by first
wrapping it in an AnyView
.
ModalPresentationView
updates its internal state to pass the destination
view into the presentation(_:)
view modifier. It also sets a dismiss()
closure on the environment of the presented view using the
.modalDismissAction
environment key.
Finally, ModalDismissButton
reads the dismiss()
closure from the
environment and calls it when tapped, causing ModalPresentationView
to
update its internal state again and remove the presented modal.
Contributing
See the CONTRIBUTING document for details about how you can contribute.
License
ModalPresentationView is Copyright (c) 2019 thoughtbot, inc.
It contains free software that may be redistributed
under the terms specified in the LICENSE file.
About

ModalPresentationView is maintained by Adam Sharp and funded by thoughtbot, inc.
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
We love open source software!
See our other projects
or hire us to help build your product.
ModalPresentationView
Takes the boilerplate out of managing modal presentations in SwiftUI.
Background
SwiftUI currently provides two different ways to manage modal presentations:
The simplest,
PresentationButton
, accepts aDestination
parameter and presents it over the current context. It doesn’t provide a control for manual dismissal, instead appearing to rely on the interactive dismissal gesture that’s part of the new default.pageSheet
modal presentation style.Alternatively, the more powerful
presentation(_:)
modifier allows you to take control of the presentation state yourself, by accepting an optional parameter of typeModal
.ModalPresentationView
sits in the middle, providing aModalPresentationButton
control with the same API asPresentationButton
, but additionally:Unlike the
presentation(_:)
modifier, automatically manages the state of the modal via a newModalNavigationView
. If you’re familiar withNavigationView
, then you already know how to use it.Provides for manual dismissal via
ModalDismissButton
, in addition to the existing interactive dismiss gesture.Demo
Example code
Installation
How does it work?
Internally,
ModalPresentationView
defines two custom environment keys, which it then uses to communicate between the container and the buttons, regardless of where they’re placed in your view hierarchy.Firstly,
ModalPresentationView
injects apresent(_:)
closure into the environment using the.modalPresentAction
key.When tapped,
ModalPresentationButton
reads the closure from the environment and calls it to notifyModalPresentationView
to trigger a presentation. The presentation button passes the destination view into the closure by first wrapping it in anAnyView
.ModalPresentationView
updates its internal state to pass the destination view into thepresentation(_:)
view modifier. It also sets adismiss()
closure on the environment of the presented view using the.modalDismissAction
environment key.Finally,
ModalDismissButton
reads thedismiss()
closure from the environment and calls it when tapped, causingModalPresentationView
to update its internal state again and remove the presented modal.Contributing
See the CONTRIBUTING document for details about how you can contribute.
License
ModalPresentationView is Copyright (c) 2019 thoughtbot, inc. It contains free software that may be redistributed under the terms specified in the LICENSE file.
About
ModalPresentationView is maintained by Adam Sharp and funded by thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc.
We love open source software! See our other projects or hire us to help build your product.