> ios-navigation
Opinionated SwiftUI navigation enforcement for iOS 26 / Swift 6.2 clinic modular MVVM-C apps. Enforces Domain coordinator protocols, App-target `DependencyContainer` + concrete coordinators + route shells, `NavigationPath` ownership, coordinator-owned modal state, deep-link/state-restoration readiness, and stale-while-revalidate/optimistic queued flow compatibility. Use when designing or refactoring clinic navigation flows.
curl "https://skillshub.wtf/pproenca/dot-skills/ios-navigation?format=md"iOS Navigation (Modular MVVM-C)
Opinionated navigation enforcement for SwiftUI apps using the clinic modular architecture. Focus on coordinator + route shell wiring, feature isolation, and resilient push/sheet/deep-link flows.
Non-Negotiable Constraints (iOS 26 / Swift 6.2)
@Equatablemacro on every navigation view,AnyViewnever@Observableeverywhere,ObservableObject/@Publishednever- App-target coordinators own
NavigationPath; route shells own.navigationDestinationmappings - Coordinator-owned modal state, inline
@Statebooleans for sheets never - Domain layer defines coordinator protocols; concrete coordinators stay out of feature modules
Clinic Architecture Contract (iOS 26 / Swift 6.2)
All guidance in this skill assumes the clinic modular MVVM-C architecture:
- Feature modules import
Domain+DesignSystemonly (neverData, never sibling features) - App target is the convergence point and owns
DependencyContainer, concrete coordinators, and Route Shell wiring Domainstays pure Swift and defines models plus repository,*Coordinating,ErrorRouting, andAppErrorcontractsDataowns SwiftData/network/sync/retry/background I/O and implements Domain protocols- Read/write flow defaults to stale-while-revalidate reads and optimistic queued writes
- ViewModels call repository protocols directly (no default use-case/interactor layer)
When to Apply
Reference these guidelines when:
- Designing navigation hierarchies with NavigationStack or NavigationSplitView
- Choosing between push, sheet, and fullScreenCover
- Implementing hero animations, zoom transitions, or gesture-driven dismissals
- Building multi-step flows (onboarding, checkout, registration)
- Using @Observable with @Environment and @Bindable for shared navigation state
- Reviewing code for navigation anti-patterns and modular architecture compliance
- Adding deep linking, state restoration, or tab persistence
- Ensuring VoiceOver and reduce motion support for navigation
Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Navigation Architecture | CRITICAL | arch- |
| 2 | Navigation Anti-Patterns | CRITICAL | anti- |
| 3 | Transition & Animation | HIGH | anim- |
| 4 | Modal Presentation | HIGH | modal- |
| 5 | Flow Orchestration | HIGH | flow- |
| 6 | Navigation Performance | MEDIUM-HIGH | perf- |
| 7 | Navigation Accessibility | MEDIUM | ally- |
| 8 | State & Restoration | MEDIUM | state- |
Quick Reference
1. Navigation Architecture (CRITICAL)
arch-navigation-stack- Use NavigationStack over deprecated NavigationViewarch-value-based-links- Use value-based NavigationLink over destination closuresarch-destination-registration- Register navigationDestination at stack rootarch-destination-item- Use navigationDestination(item:) for optional-based navigation (iOS 26 / Swift 6.2)arch-route-enum- Define routes as Hashable enumsarch-split-view- Use NavigationSplitView for multi-column layoutsarch-coordinator- Extract navigation logic into Observable coordinatorarch-observable-environment- Use @Environment with @Observable and @Bindable for shared statearch-deep-linking- Handle deep links by appending to NavigationPatharch-navigation-path- Use NavigationPath for heterogeneous type-erased navigationarch-equatable-views- Apply @Equatable macro to every navigation viewarch-observable-only- Use @Observable only — never ObservableObject or @Publishedarch-no-anyview- Never use AnyView in navigation — use @ViewBuilder or genericsarch-coordinator-modals- Present all modals via coordinator — never inline @State
2. Navigation Anti-Patterns (CRITICAL)
anti-mixed-link-styles- Avoid mixing NavigationLink(destination:) with NavigationLink(value:)anti-scattered-destinations- Avoid scattering navigationDestination across viewsanti-shared-stack- Avoid sharing NavigationStack across tabsanti-hidden-back-button- Avoid hiding back button without preserving swipe gestureanti-navigation-in-init- Avoid heavy work in view initializersanti-hamburger-menu- Avoid hamburger menu navigationanti-programmatic-tab-switch- Avoid programmatic tab selection changes
3. Transition & Animation (HIGH)
anim-zoom-transition- Use zoom navigation transition for hero animations (iOS 18+)anim-matched-geometry-same-view- Use matchedGeometryEffect only within same view hierarchyanim-spring-config- Use modern spring animation syntax (iOS 26 / Swift 6.2)anim-gesture-driven- Use interactive spring animations for gesture-driven transitionsanim-transition-source-styling- Style transition sources with shape and backgroundanim-reduce-motion-transitions- Respect reduce motion for all navigation animationsanim-scroll-driven- Use onScrollGeometryChange for scroll-driven transitions (iOS 18+)
4. Modal Presentation (HIGH)
modal-sheet-vs-push- Use push for drill-down, sheet for supplementary contentmodal-detents- Use presentation detents for contextual sheet sizingmodal-fullscreen-cover- Use fullScreenCover only for immersive standalone experiencesmodal-sheet-placement- Place .sheet on container view, not on NavigationLinkmodal-interactive-dismiss- Guard unsaved changes with interactiveDismissDisabledmodal-nested-navigation- Use separate NavigationStack inside modals
5. Flow Orchestration (HIGH)
flow-tab-independence- Give each tab its own NavigationStackflow-multi-step- Use NavigationStack with route array for multi-step flowsflow-sidebar-navigation- Use NavigationSplitView with selection binding for sidebarflow-tab-sidebar-adaptive- Use sidebarAdaptable TabView for iPad tab-to-sidebar (iOS 18+)flow-pop-to-root- Implement pop-to-root by clearing NavigationPathflow-screen-independence- Keep screens independent of parent navigation context
6. Navigation Performance (MEDIUM-HIGH)
perf-lazy-destinations- Use value-based NavigationLink for lazy destination constructionperf-task-modifier- Use .task for async data loading on navigationperf-state-object-ownership- Own @Observable state with @State, pass as plain propertyperf-avoid-body-side-effects- Avoid side effects in view body
7. Navigation Accessibility (MEDIUM)
ally-rotor-headers- Mark navigation section headers for VoiceOver rotorally-focus-after-navigation- Manage focus after programmatic navigation eventsally-group-navigation-elements- Group related navigation elements to reduce swipe countally-hide-decorative-navigation- Hide decorative navigation elements from VoiceOverally-keyboard-focus- Use @FocusState for keyboard navigation in forms
8. State & Restoration (MEDIUM)
state-codable-routes- Make route enums Codable for navigation persistencestate-scene-storage- Use SceneStorage for per-scene navigation persistencestate-tab-persistence- Persist selected tab with SceneStoragestate-deep-link-urls- Parse deep link URLs into route enumsstate-avoid-app-level-path- Avoid defining NavigationPath at App level
How to Use
Read individual reference files for detailed explanations and code examples:
- Section definitions - Category structure and impact levels
- Rule template - Template for adding new rules
Reference Files
| File | Description |
|---|---|
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for new rules |
| metadata.json | Version and reference information |
> related_skills --same-repo
> rust-write-tests
Skill for writing expert-level Rust tests. Teaches the "What Could Break?" framework, five transformations from superficial to expert tests, flake hunting protocol, intent-based assertions, naming conventions, and a mandatory self-review checklist. Triggers on writing Rust tests, designing test cases, improving test quality, or reviewing test coverage.
> rust-implement
Write production-grade Rust code using a multi-pass approach. Design types first, then implement, then simplify, then verify with automated lint. Use this skill whenever writing new Rust functions, structs, modules, or features. Triggers on Rust implementation, new Rust code, Rust functions, Rust modules, error handling in Rust, async Rust, or type design in Rust.
> valid-skill
A valid test skill with proper formatting. This skill should pass all validations and serves as a reference for the expected format.
> too-long-skill
This skill has more than 500 lines which should fail validation.