Snippets
SwiftUI Sheets, Popovers, and Detents
Present focused secondary work with sheets, popovers, and detents while keeping dismissal and size behavior explicit.
5 min readUpdated 2026-06
import SwiftUI
struct AccountView: View {
@State private var editing = false
var body: some View {
Button("Edit Settings") { editing = true }
.sheet(isPresented: $editing) {
SettingsEditor()
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
}
}
}
struct SettingsEditor: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
NavigationStack {
Form { Toggle("Email updates", isOn: .constant(true)) }
.navigationTitle("Settings")
.toolbar { Button("Done") { dismiss() } }
}
}
}Implementation notes
Use item-based presentation when the sheet content depends on selected data.
Detents make sheets feel less heavy, but the content still needs to work at each selected height.
If users can lose work, combine a disabled interactive dismissal with an explicit cancel or save action.
Checklist
Test the sheet at every detent you expose.
Put dismiss logic inside the presented view when it owns the completion flow.
Check compact-width adaptation for popovers.
Related reference
SwiftUI Alerts and Confirmation Dialogs
Use alerts for urgent decisions and confirmationDialog for action choices that can adapt across iPhone, iPad, and macOS.
SwiftUI Toolbar and ControlGroup Actions
Place primary and secondary commands in toolbars with predictable placement, grouping, tinting, and keyboard-aware behavior.
SwiftUI Frame, Padding, and Layout Priority
Control layout by combining flexible frames, padding, fixedSize, and layoutPriority rather than guessing with offsets.