Use this skill to build, review, or improve SwiftUI features with correct state management, modern API usage, Swift concurrency best practices, optimal view composition, and iOS 26+ Liquid Glass styling. Prioritize native APIs, Apple design guidance, and performance-conscious patterns. This skill focuses on facts and best practices without enforcing specific architectural patterns. - Check property wrapper usage against the selection guide (see `references/state-management.md`) - Verify mode
references/state-management.md)references/modern-apis.md)references/view-structure.md)references/performance-patterns.md)references/list-patterns.md)references/animation-basics.md, references/animation-transitions.md)references/liquid-glass.md)@Observable over ObservableObject)references/modern-apis.md)references/view-structure.md)references/performance-patterns.md)references/list-patterns.md)references/animation-basics.md, references/animation-transitions.md)UIImage(data:) is used (as optional optimization, see references/image-optimization.md)references/state-management.md)references/modern-apis.md)@Observable for shared state (with @MainActor if not using default actor isolation)references/view-structure.md)references/layout-best-practices.md)references/animation-basics.md, references/animation-transitions.md, references/animation-advanced.md)references/liquid-glass.md)#available and provide fallbacks@Observable over ObservableObject for new code@Observable classes with @MainActor unless using default actor isolation@State and @StateObject as private (makes dependencies clear)@State or @StateObject (they only accept initial values)@State with @Observable classes (not @StateObject)@Binding only when child needs to modify parent state@Bindable for injected @Observable objects needing bindingslet for read-only values; var + .onChange() for reactive reads@StateObject for owned ObservableObject; @ObservedObject for injectedObservableObject doesn't work (pass nested objects directly); @Observable handles nesting fineforegroundStyle() instead of foregroundColor()clipShape(.rect(cornerRadius:)) instead of cornerRadius()Tab API instead of tabItem()Button instead of onTapGesture() (unless need location/count)NavigationStack instead of NavigationViewnavigationDestination(for:) for type-safe navigationonChange() variantImageRenderer for rendering SwiftUI views.sheet(item:) instead of .sheet(isPresented:) for model-based contentdismiss() internallyScrollViewReader for programmatic scrolling with stable IDsUIScreen.main.bounds for sizingGeometryReader when alternatives exist (e.g., containerRelativeFrame()).format parameters, not String(format:))localizedStandardContains() for user-input filtering (not contains()).blue vs Color.blue).task modifier for automatic cancellation of async work.task(id:) for value-dependent tasksbody simple and pure (no side effects or complex logic)@ViewBuilder functions only for small, simple sections@ViewBuilder let content: Content over closure-based content propertiesonReceive, onChange, scroll handlersLazyVStack/LazyHStack for large listsForEach (never .indices for dynamic content)ForEach elementForEach (prefilter and cache)AnyView in list rowsUIImage(data:) is encountered (as optional optimization)GeometryReader)Self._printChanges() to debug unexpected view updates.animation(_:value:) with value parameter (deprecated version without value is too broad)withAnimation for event-driven animations (button taps, gestures)offset, scale, rotation) over layout changes (frame) for performanceAnimatable implementations must have explicit animatableData.phaseAnimator for multi-step sequences (iOS 17+).keyframeAnimator for precise timing control (iOS 17+).transaction(value:) for reexecutionglassEffect, GlassEffectContainer, and glass button stylesGlassEffectContainer.glassEffect() after layout and visual modifiers.interactive() only for tappable/focusable elementsglassEffectID with @Namespace for morphing transitions@Stateprivate), or owned @Observable class@Binding@Bindable@Observable needing bindingsletvar.onChange()@StateObjectObservableObject (use @State with @Observable instead)@ObservedObjectObservableObjectforegroundColor()foregroundStyle()cornerRadius()clipShape(.rect(cornerRadius:))tabItem()Tab APIonTapGesture()Button (unless need location/count)NavigationViewNavigationStackonChange(of:) { value in }onChange(of:) { old, new in } or onChange(of:) { }fontWeight(.bold)bold()GeometryReadercontainerRelativeFrame() or visualEffect()showsIndicators: false.scrollIndicators(.hidden)String(format: "%.2f", value)Text(value, format: .number.precision(.fractionLength(2)))string.contains(search)string.localizedStandardContains(search) (for user input)// Basic glass effect with fallback if #available(iOS 26, *) { content .padding() .glassEffect(.regular.interactive(), in: .rect(cornerRadius: 16)) } else { content .padding() .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16)) } // Grouped glass elements GlassEffectContainer(spacing: 24) { HStack(spacing: 24) { GlassButton1() GlassButton2() } } // Glass buttons Button("Confirm") { } .buttonStyle(.glassProminent)
@Observable instead of ObservableObject for new code@Observable classes marked with @MainActor (if needed)@State with @Observable classes (not @StateObject)@State and @StateObject properties are private@State or @StateObject@Binding only where child modifies parent state@Bindable for injected @Observable needing bindingsObservableObject avoided (or passed directly to child views)references/modern-apis.md)foregroundStyle() instead of foregroundColor()clipShape(.rect(cornerRadius:)) instead of cornerRadius()Tab API instead of tabItem()Button instead of onTapGesture() (unless need location/count)NavigationStack instead of NavigationViewUIScreen.main.boundsGeometryReader when possiblereferences/sheet-navigation-patterns.md).sheet(item:) for model-based sheetsnavigationDestination(for:) for type-safe navigationreferences/scroll-patterns.md)ScrollViewReader with stable IDs for programmatic scrolling.scrollIndicators(.hidden) instead of initializer parameterreferences/text-formatting.md)String(format:))localizedStandardContains() for search filteringreferences/view-structure.md)@ViewBuilder let content: Contentreferences/performance-patterns.md)body kept simple and pure (no side effects)bodybodyreferences/list-patterns.md).indices)AnyView in list rowsreferences/layout-best-practices.md)references/animation-basics.md, references/animation-transitions.md, references/animation-advanced.md).animation(_:value:) with value parameterwithAnimation for event-driven animationsAnimatable has explicit animatableData implementation.transaction(value:) for reexecution#available(iOS 26, *) with fallback for Liquid GlassGlassEffectContainer.glassEffect() applied after layout/appearance modifiers.interactive() only on user-interactable elementsreferences/state-management.md - Property wrappers and data flow (prefer @Observable)references/view-structure.md - View composition, extraction, and container patternsreferences/performance-patterns.md - Performance optimization techniques and anti-patternsreferences/list-patterns.md - ForEach identity, stability, and list best practicesreferences/layout-best-practices.md - Layout patterns, context-agnostic views, and testabilityreferences/modern-apis.md - Modern API usage and deprecated replacementsreferences/animation-basics.md - Core animation concepts, implicit/explicit animations, timing, performancereferences/animation-transitions.md - Transitions, custom transitions, Animatable protocolreferences/animation-advanced.md - Transactions, phase/keyframe animations (iOS 17+), completion handlers (iOS 17+)references/sheet-navigation-patterns.md - Sheet presentation and navigation patternsreferences/scroll-patterns.md - ScrollView patterns and programmatic scrollingreferences/text-formatting.md - Modern text formatting and string operationsreferences/image-optimization.md - AsyncImage, image downsampling, and optimizationreferences/liquid-glass.md - iOS 26+ Liquid Glass API@MainActor and @Observable