swiftui-presentation-api
SKILL.md
Presentation Modifiers API Reference
Lifecycle Position
Phase 3 API Reference — load during implementation when presenting sheets, alerts, popovers, or inspectors. Dispatched from autonomous-ui-workflow Phase 2 research table.
Sheet / Cover / Popover
.sheet(isPresented: $show) { Content() }
.sheet(item: $item) { item in Detail(item: item) }
.fullScreenCover(isPresented: $show) { Content() }
.popover(isPresented: $show, arrowEdge: .top) { Content() }
Sheet Configuration
| Modifier | Purpose |
|---|---|
.presentationDetents([.medium, .large]) |
Available heights |
.presentationDetents(_:selection:) |
Programmatic height control |
.presentationDragIndicator(_:) |
Show/hide drag handle |
.presentationBackground(_:) |
Custom background style |
.presentationCornerRadius(_:) |
Corner radius |
.presentationSizing(_:) |
Size control |
.interactiveDismissDisabled() |
Prevent swipe dismiss |
.presentationBackgroundInteraction(_:) |
Interact behind sheet |
.presentationCompactAdaptation(_:) |
Adapt for compact: .sheet, .popover, .fullScreenCover |
Alerts
.alert("Title", isPresented: $show) {
Button("OK") { }
} message: {
Text("Description")
}
.alert("Save Failed", isPresented: $didError, presenting: details) { d in
Button(role: .destructive) { } label: { Text("Delete \(d.name)") }
Button("Retry") { }
} message: { d in Text(d.error) }
Rules: All actions dismiss. System may reorder by role. No actions = "OK" added.
Confirmation Dialog
.confirmationDialog("Delete?", isPresented: $show) {
Button("Delete", role: .destructive) { delete() }
Button("Cancel", role: .cancel) { }
}
Inspector
.inspector(isPresented: $showInspector) { InspectorContent() }
macOS Window Behaviors
.windowFullScreenBehavior(.disabled)
.windowMinimizeBehavior(.disabled)
.windowDismissBehavior(.disabled)
.windowToolbarFullScreenVisibility(.visible)
When to Use Which
| Need | Use |
|---|---|
| Detail view with dismiss | .sheet(item:) { item in DetailView(item) } |
| Confirmation before destructive action | .confirmationDialog("Delete?", isPresented:) |
| Simple alert with message | .alert("Title", isPresented:) { } message: { } |
| Contextual popover | .popover(isPresented:) { } |
| Side panel on iPad/Mac | .inspector(isPresented:) |
| Bottom sheet with drag | .sheet + .presentationDetents([.medium, .large]) |
| Full screen takeover | .fullScreenCover(item:) |
Sheet Best Practices
// PREFER: model-based presentation (no stale data)
.sheet(item: $selectedItem) { item in
DetailView(item: item)
}
// AVOID: boolean presentation (can show stale data)
.sheet(isPresented: $showDetail) {
DetailView(item: selectedItem) // selectedItem might be stale
}
// Sheets own their dismissal
struct DetailView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
NavigationStack {
content
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") { dismiss() }
}
}
}
}
}
// Programmatic detent control
@State private var detent: PresentationDetent = .medium
.sheet(isPresented: $show) {
SheetContent()
.presentationDetents([.medium, .large], selection: $detent)
}
macOS Window Presentation
// New window (macOS)
@Environment(\.openWindow) private var openWindow
Button("Open") { openWindow(id: "detail") }
// Inspector panel (macOS/iPadOS)
.inspector(isPresented: $showInspector) {
InspectorView()
.inspectorColumnWidth(min: 200, ideal: 300, max: 400)
}
Common Mistakes
.sheet(isPresented:)with stale captured data — use.sheet(item:)for model-based presentation- Missing
@Environment(\.dismiss)— sheets should dismiss themselves, not rely on parent state - Nested sheets (sheet presenting another sheet) — breaks on some OS versions. Use NavigationStack inside the sheet instead
- Missing
NavigationStackinside sheets — no toolbar placement support without it .popoverwithout.presentationCompactAdaptation(.sheet)— on iPhone, popovers become sheets by default but may need explicit control
Checklist
- Using
.sheet(item:)over.sheet(isPresented:)for data-driven presentation - Sheets contain their own
NavigationStackfor toolbar support - Sheets use
@Environment(\.dismiss)for self-dismissal - Confirmation dialogs used for destructive actions (not alerts)
-
.presentationDetentsspecified when bottom sheet behavior is needed - macOS inspectors use
.inspectorColumnWidth()for sizing
Cross-References
swiftui-input-api— forms presented inside sheetsswiftui-ui-patterns— sheet/navigation patterns in review checklistswiftui-material-api— material backgrounds in presented content
Weekly Installs
2
Repository
kmshdev/claude-…-toolkitFirst Seen
2 days ago
Security Audits
Installed on
mcpjam2
claude-code2
replit2
junie2
windsurf2
zencoder2