SwiftUI.cc
Guides
GuideNavigationIntermediate

How to Dismiss Sheet Programmatically in SwiftUI

Learn how to programmatically dismiss sheets in SwiftUI using presentationMode for iOS 15 and dismiss action for iOS 16+.

6 min readUpdated 2026-06

Overview

In SwiftUI, sheets are presented modally using the .sheet modifier, and by default, users dismiss them by swiping down or tapping outside the sheet. However, there are cases where you need to dismiss a sheet programmatically — for instance, after completing a form or handling a user action. This guide covers two primary methods: using presentationMode for iOS 15 and the newer dismiss API introduced in iOS 16.

The Approach

For iOS 15, we use presentationMode from the Environment to dismiss the sheet. Starting from iOS 16, Apple introduced a simpler dismiss method that doesn't require binding or managing the presentation state manually.

Here's a basic SwiftUI view that demonstrates both approaches:

import SwiftUI

struct ContentView: View {
    @State private var isPresented = false

    var body: some View {
        Button("Present Sheet") {
            isPresented = true
        }
        .sheet(isPresented: $isPresented) {
            if #available(iOS 16.0, *) {
                DismissableView(isPresented: $isPresented)
            } else {
                DismissableViewLegacy(isPresented: $isPresented)
            }
        }
    }
}

// iOS 16+
struct DismissableView: View {
    @Binding var isPresented: Bool

    var body: some View {
        Button("Dismiss Sheet") {
            isPresented = false
        }
        .padding()
    }
}

// iOS 15 and earlier
struct DismissableViewLegacy: View {
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        Button("Dismiss Sheet") {
            presentationMode.wrappedValue.dismiss()
        }
        .padding()
    }
}

Step-by-Step Breakdown

  1. ContentView: A main view that presents a sheet using .sheet. It uses a @State variable isPresented to control the presentation.
  2. iOS Version Check: Inside the sheet, we check the iOS version and present the appropriate view (DismissableView for iOS 16+ and DismissableViewLegacy for iOS 15).
  3. iOS 16+ Dismiss: DismissableView uses a @Binding to the isPresented state and sets it to false to dismiss the sheet.
  4. iOS 15 Dismiss: DismissableViewLegacy uses @Environment(\.presentationMode) to access the presentationMode environment value. Calling dismiss() on it programmatically dismisses the sheet.

This setup ensures backward compatibility while using the most modern approach available on supported devices.

Common Variations

1. Dismissing from a Nested View (iOS 16+)

Sometimes, you might need to dismiss a sheet from a deeply nested view. Here's how you can do it without passing the @Binding all the way down:

struct DismissableViewNested: View {
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        Button("Dismiss Sheet") {
            dismiss()
        }
    }
}

This uses the dismiss environment value introduced in iOS 16, which is cleaner and avoids the need for a binding.

2. Dismissing with Animation (iOS 15+)

If you want to animate the dismissal (e.g., fade out), you can wrap the dismiss call in an animation block:

withAnimation {
    isPresented = false
}

Or for iOS 15:

withAnimation {
    presentationMode.wrappedValue.dismiss()
}

Pitfalls to Avoid

  1. Using presentationMode in iOS 16+: While it still works, it's deprecated in favor of the dismiss() environment value. Use the newer API for better clarity and future compatibility.
  2. Overusing @Binding: Passing a @Binding through multiple layers can become cumbersome. Use @Environment(\.dismiss) in iOS 16+ for cleaner code.
  3. Dismissing from Background Threads: Always ensure that dismissal logic runs on the main thread. If you're dismissing after a network request or async task, wrap it in DispatchQueue.main.async.
  • how-to-present-sheet-in-swiftui
  • how-to-use-environment-in-swiftui
  • how-to-handle-user-interactions-in-swiftui