TechnologiesSwiftUIPresentation and Dialogs

DismissBehavior struct

iOSmacOStvOSwatchOSvisionOS✓ renders

Programmatic window dismissal behaviors.

How it works

DismissBehavior is a type whose constant values describe whether an interaction within a presentation — such as a sheet or popover — is allowed to dismiss that presentation. SwiftUI uses these values to negotiate between system-provided gestures, like swipe-to-dismiss, and the requirements of your interface, where some flows must run to completion before the user moves on. Reach for it when a presentation needs to assert control over its own lifecycle rather than letting an incidental gesture tear it down. It turns dismissal from an implicit, gesture-driven event into a behavior you can declare.

  1. Choose between the enabled and disabled constants

    DismissBehavior exposes its values as static members — enabled permits an interaction to dismiss the presentation, while disabled prevents it. You select the constant that matches the contract your flow needs: a casual sheet can stay enabled, but a step the user must acknowledge resolves to disabled so the presentation persists until you explicitly close it, as the demo's Done button does with showingSheet = false.

  2. Present the content the behavior governs

    A DismissBehavior only has meaning relative to an active presentation, so it attaches to content surfaced by a modifier like .sheet(isPresented:). In the example the sheet is driven by $showingSheet, and everything inside that closure — including its dismissal rules — is the scope the behavior controls.

  3. Disable the interactive gesture with interactiveDismissDisabled

    The clearest expression of disabled behavior is the interactiveDismissDisabled(true) modifier, which tells SwiftUI to suppress the swipe-to-dismiss gesture on the presentation. Passing true here is what makes the sheet refuse to be flicked away; passing false would restore the system's default enabled behavior.

  4. Provide an explicit exit path

    When dismissal is disabled, the system gesture no longer offers a way out, so your interface must supply one. The demo does this with Button("Done") { showingSheet = false }, flipping the @State flag that drives isPresented — the deliberate dismissal that a locked presentation requires.

Try it — Change interactiveDismissDisabled(true) to interactiveDismissDisabled(false) and the sheet will once again accept the swipe-down gesture, restoring the default enabled behavior.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

DismissBehavior.swift
struct DismissBehaviorDemo: View {
    @State private var showingSheet = true

    var body: some View {
        VStack(spacing: 12) {
            Text("Sheet stays put")
                .font(.headline)
            Text("Swipe-to-dismiss is disabled.")
                .foregroundStyle(.secondary)
        }
        .padding()
        .sheet(isPresented: $showingSheet) {
            VStack(spacing: 16) {
                Text("Important Step")
                    .font(.title2.bold())
                Text("You can't swipe this away.")
                    .foregroundStyle(.secondary)
                Button("Done") { showingSheet = false }
                    .buttonStyle(.borderedProminent)
            }
            .padding()
            .presentationDetents([.medium])
            .interactiveDismissDisabled(true)
        }
    }
}
Live preview
Sheet stays put Swipe-to-dismiss is disabled. Important Step You can't swipe this away. Done
Sheet stays put Swipe-to-dismiss is disabled. Important Step You can't swipe this away. Done
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →