How to present a sheet modally in SwiftUI

In this tutorial we’re going to learn how to present a new sheet view modally in SwiftUI after pressing a button. In order to achieve it, use .sheet() modifier on the Button view.

In its simplest form, the .sheet() modifier takes as an argument a binding which tells it whether to show the sheet, and a content closure which returns new view to be presented. Take a look at a complete example below. Pressing the “Show Sheet View” button triggers the sheet to be presented modally on top of current view:

import SwiftUI

struct SheetView: View {
    var body: some View {
        Text("Sheet View")
    }
}
struct ContentView: View {
    @State var showSheetView = false

    var body: some View {
        Button(action: {
            self.showSheetView.toggle()
        }) {
            Text("Show Sheet View")
        }.sheet(isPresented: $showSheetView) {
            SheetView()
        }
    }
}

If you would like to execute some code when the sheet is dismissed, use a version of the sheet modifier with onDismiss argument and pass an additional closure:

Button(action: {
    self.showSheetView.toggle()
}) {
    Text("Show Sheet View")
}.sheet(isPresented: $showSheetView, onDismiss: {
    print("Code executed when the sheet dismisses")
}) {
    SheetView()
}

Present a sheet view with Navigation Bar and a Done button

Let’s tackle a more sophisticated example with the sheet view being a NavigationView and having a Navigation Bar with a trailing Done button (navigation bar item) which dismisses the sheet. I’ve previously covered how to add a button to navigation bar in SwiftUI so check it out if you’d like to learn more.

Being able to dismiss the sheet view means that we’ll have to pass the showSheetView binding from ContentView to SheetView and update its value from within ContentView when user presses Done button.

This can be achieved by updating the SheetView with the following:

  1. Declare its own @Binding to store the reference to showSheetView
  2. Update the value of SheetView’s showSheetView when Done button is pressed

Take a look at a complete code example:

struct SheetView: View {
    @Binding var showSheetView: Bool
    
    var body: some View {
        NavigationView {
            Text("Sheet View content")
            .navigationBarTitle(Text("Sheet View"), displayMode: .inline)
                .navigationBarItems(trailing: Button(action: {
                    print("Dismissing sheet view...")
                    self.showSheetView = false
                }) {
                    Text("Done").bold()
                })
        }
    }
}

struct ContentView: View {
    @State var showSheetView = false
    
    var body: some View {
        Button(action: {
            self.showSheetView.toggle()
        }) {
            Text("Show Sheet View")
        }.sheet(isPresented: $showSheetView) {
            SheetView(showSheetView: self.$showSheetView)
        }
    }
}
Presenting a sheet modally in SwiftUI
Presenting a sheet modally in SwiftUI

Related tutorials: