How to Present and Dismiss a Modal in SwiftUI
Tags: swiftui, swift, ios
Published: 2019-08-26 15:54:35

---
title: How to Present and Dismiss a Modal in SwiftUI
published: true
description: In this post, we will cover how to present and dismiss a modal view.
canonical_url: https://appsbymw.com/blog/2019/08/26/present-dismiss-modal-in-swiftui
tags: swiftui, swift, ios
series: SwiftUI Examples
---


# How to Present and Dismiss a Modal in SwiftUI

In this post, we will cover how to present and dismiss a modal view.

![](https://github.com/maeganjwilson/swiftui-show-modal-tutorial/blob/master/blog/images/present-dismiss.gif?raw=true)

Find the source code at this Github Repo.

{% github maeganjwilson/swiftui-show-modal-tutorial %}

**NOTE**: this tutorial is using **Xcode 11** and has been tested using **iOS 13.1.2**.

Let's get started by making a new project using SwiftUI. When creating a new project, make sure that the language is set to Swift, and the User Interface is configured to SwiftUI like in the picture below.

![](https://github.com/maeganjwilson/swiftui-show-modal-tutorial/blob/master/blog/images/new-project.png?raw=true)

## `show_modal` variable

Now that the project is made, we need to open the `ContentView.swift` file to declare a variable that determines whether or not to present the modal.

```swift
struct ContentView: View {
    // Declare this state variable below
    @State private var show_modal: Bool = false

    var body: some View {
        Text("Hello World")
    }
}
```

The variable has to be a binding variable and one that can update the view when changing, which is why we declare it as a State variable.

## Button to change the state!

Let's change the `Text()` to a `Button()` that sets `show_modal` to `true`.

```swift
Button(action: {
        print("Button Pushed")
        self.show_modal = true
    }) {
        Text("Show Modal")
}
```

I added a `print()` statement to make sure the button works.
Go ahead and run the app (Command + R) and click on the button. By clicking on the button, "Button Pushed" will be printed in the console.

## Create the Modal View

Now, let's create the modal view. Create a new file and change the Text to "This is a Modal." It should look like the code snippet below.

```swift
import SwiftUI

struct ModalView: View {
    var body: some View {
        Text("This is a modal")
    }
}
```

## Making the Modal Appear

It's time to make the modal appear from the button push on the first view. Open `ContentView.swift` and add the following to the button.

```swift
Button(action: {
        print("Button Pushed")
        self.show_modal = true
    }) {
        Text("Show Modal")
    }.sheet(isPresented: self.$show_modal) {
         ModalView()
        }
```

What does `.sheet() // more code` do? It is deciding if `ModalView` should be presented when `show_modal` changes.

`.sheet(isPresented: Binding<Bool>){ /* View to present */}` is a modifier that can present the view when `isPresented` is `true`. In our example, `show_modal` is a `Binding<Bool>` because it is declared with `@State`. We also set the view to be presented as `ModalView()`.

`ContentView.swift` should now be complete and look like this.

```swift
import SwiftUI

struct ContentView: View {
    @State private var show_modal: Bool = false

    var body: some View {
        Button(action: {
            print("Button Pushed")
            self.show_modal = true
        }) {
            Text("Show Modal")
        }.sheet(isPresented: self.$show_modal) {
            ModalView()
        }
    }
}

```

Running the application right now, we can dismiss the modal by dragging down from the top of the modal.
![](https://github.com/maeganjwilson/swiftui-show-modal-tutorial/blob/master/blog/images/drag-to-dismiss.gif?raw=true)

## Add a dismiss button

Dragging works to dismiss, but sometimes users would instead hit a button, or maybe you want the user to hit the button to confirm, and a drag cancels the operation. To add a button to dismiss the modal, we need to put add an Environment variable for `presentationMode` and then call `presentationMode.wrappedValue.dismiss()`. Here is how it looks in `ModalView.swift`.

```swift
struct ModalView: View {
    // 1. Add the environment variable
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        // 2. Embed Text in a VStack
        VStack {
            // 3. Add a button with the following action
            Button(action: {
                print("dismisses form")
                self.presentationMode.wrappedValue.dismiss()
            }) {
                Text("Dismiss")
            }.padding(.bottom, 50)
            Text("This is a modal")
        }
    }
}
```

I'm going to break down what we did.

1. **Add the environment variable.** This environment variable is what determines when to dismiss the modal.
2. **Embed the Text in a VStack.** We do this to be able to have a Button view on top of the Text.
3. **Add a button with the following action.** The action in the button is what to perform when the button is tapped. `self.presentaionMode.wrappedValue.dismiss()` is the method that dismisses the Modal.

Now, running the application, we can dismiss the view either by dragging or by tapping on the button.

![](https://github.com/maeganjwilson/swiftui-show-modal-tutorial/blob/master/blog/images/button-drag.gif?raw=true)

---

If you enjoy my posts, please consider sharing it or Buying me a Coffee!

<a href="https://www.buymeacoffee.com/appsbymw" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/arial-blue.png" alt="Buy Me A Coffee" style="height: 51px !important;width: 217px !important;" ></a>

---

# EDIT #1:

I was asked by [@cwhooten](https://twitter.com/cwhooten) how to make a list that presents a dynamic modal. [You can find that answer as a branch to the original example by clicking on this sentence](https://github.com/maeganjwilson/swiftui-show-modal-tutorial/tree/list-example).


# EDIT #2:
Updated the note at the top.

# EDIT #3:
Updated the note at the top since it has been tested with Release Xcode and Release iOS 13.