swiftui-ui-patterns
SwiftUI UI Patterns
Quick start
Choose a track based on your goal:
Existing project
- Identify the feature or screen and the primary interaction model (list, detail, editor, settings, tabbed).
- Find a nearby example in the repo with
rg "TabView\("or similar, then read the closest SwiftUI view. - Apply local conventions: prefer SwiftUI-native state, keep state local when possible, and use environment injection for shared dependencies.
- Choose the relevant component reference from
references/components-index.mdand follow its guidance. - Build the view with small, focused subviews and SwiftUI-native data flow.
New project scaffolding
- Start with
references/app-scaffolding-wiring.mdto wire TabView + NavigationStack + sheets. - Add a minimal
AppTabandRouterPathbased on the provided skeletons. - Choose the next component reference based on the UI you need first (TabView, NavigationStack, Sheets).
- Expand the route and sheet enums as new screens are added.
General rules to follow
- Use modern SwiftUI state (
@State,@Binding,@Observable,@Environment) and avoid unnecessary view models. - Prefer composition; keep views small and focused.
- Use async/await with
.taskand explicit loading/error states. - Maintain existing legacy patterns only when editing legacy files.
- Follow the project's formatter and style guide.
- Sheets: Prefer
.sheet(item:)over.sheet(isPresented:)when state represents a selected model. Avoidif letinside a sheet body. Sheets should own their actions and calldismiss()internally instead of forwardingonCancel/onConfirmclosures.
Workflow for a new SwiftUI view
- Define the view's state and its ownership location.
- Identify dependencies to inject via
@Environment. - Sketch the view hierarchy and extract repeated parts into subviews.
- Implement async loading with
.taskand explicit state enum if needed. - Add accessibility labels or identifiers when the UI is interactive.
- Validate with a build and update usage callsites if needed.
Component references
Use references/components-index.md as the entry point. Each component reference should include:
- Intent and best-fit scenarios.
- Minimal usage pattern with local conventions.
- Pitfalls and performance notes.
- Paths to existing examples in the current repo.
Sheet patterns
Item-driven sheet (preferred)
@State private var selectedItem: Item?
.sheet(item: $selectedItem) { item in
EditItemSheet(item: item)
}
Sheet owns its actions
struct EditItemSheet: View {
@Environment(\.dismiss) private var dismiss
@Environment(Store.self) private var store
let item: Item
@State private var isSaving = false
var body: some View {
VStack {
Button(isSaving ? "Saving…" : "Save") {
Task { await save() }
}
}
}
private func save() async {
isSaving = true
await store.save(item)
dismiss()
}
}
Adding a new component reference
- Create
references/<component>.md. - Keep it short and actionable; link to concrete files in the current repo.
- Update
references/components-index.mdwith the new entry.
Official Apple Documentation
Reference these for the latest SwiftUI APIs and integration patterns:
references/SwiftUI-WebKit-Integration.md- Official guide for integrating WebKit views in SwiftUIreferences/SwiftUI-Styled-Text-Editing.md- Rich text editing and styling in SwiftUIreferences/SwiftUI-New-Toolbar-Features.md- Latest toolbar customization and featuresreferences/SwiftUI-AlarmKit-Integration.md- AlarmKit integration patterns and examples
These documents contain official Apple patterns for iOS 26+ features and should be consulted when implementing related functionality.
More from dagba/ios-mcp
swiftui-performance-audit
Audit and improve SwiftUI runtime performance from code review and architecture. Use for requests to diagnose slow rendering, janky scrolling, high CPU/memory usage, excessive view updates, or layout thrash in SwiftUI apps, and to provide guidance for user-run Instruments profiling when code review alone is insufficient.
62swiftdata-coredata-persistence
Use when implementing data persistence in iOS apps with SwiftData or CoreData, encountering migration errors, performance issues with fetches, or choosing between persistence frameworks
42programmatic-uikit-layout
Use when building UIKit interfaces without storyboards, setting up Auto Layout constraints with anchors, creating reusable UI components, or encountering layout constraint errors and ambiguous layout warnings
37macos-spm-app-packaging
Scaffold, build, and package SwiftPM-based macOS apps without an Xcode project. Use when you need a from-scratch macOS app layout, SwiftPM targets/resources, a custom .app bundle assembly script, or signing/notarization/appcast steps outside Xcode.
23swiftui-view-refactor
Refactor and review SwiftUI view files for consistent structure, dependency injection, and Observation usage. Use when asked to clean up a SwiftUI view’s layout/ordering, handle view models safely (non-optional when possible), or standardize how dependencies and @Observable state are initialized and passed.
23swift-codable-json
Use when implementing JSON encoding/decoding with Codable, handling API responses, encountering decoding errors, managing date formats, mapping snake_case to camelCase, or dealing with nested/inconsistent JSON structures
21