{"id":"3ceea42d-dba0-462b-84da-5adcbd844d42","shortId":"rHHLjV","kind":"skill","title":"swiftui-ui-patterns","tagline":"Apply proven SwiftUI UI patterns for navigation, sheets, async state, and reusable screens.","description":"# SwiftUI UI Patterns\n\n## Quick start\n\n## When to Use\n- When creating or refactoring SwiftUI screens, flows, or reusable UI components.\n- When you need guidance on navigation, sheets, async state, previews, or component patterns.\n\nChoose a track based on your goal:\n\n### Existing project\n\n- Identify the feature or screen and the primary interaction model (list, detail, editor, settings, tabbed).\n- Find a nearby example in the repo with `rg \"TabView\\(\"` or similar, then read the closest SwiftUI view.\n- Apply local conventions: prefer SwiftUI-native state, keep state local when possible, and use environment injection for shared dependencies.\n- Choose the relevant component reference from `references/components-index.md` and follow its guidance.\n- If the interaction reveals secondary content by dragging or scrolling the primary content away, read `references/scroll-reveal.md` before implementing gestures manually.\n- Build the view with small, focused subviews and SwiftUI-native data flow.\n\n### New project scaffolding\n\n- Start with `references/app-wiring.md` to wire TabView + NavigationStack + sheets.\n- Add a minimal `AppTab` and `RouterPath` based on the provided skeletons.\n- Choose the next component reference based on the UI you need first (TabView, NavigationStack, Sheets).\n- Expand the route and sheet enums as new screens are added.\n\n## General rules to follow\n\n- Use modern SwiftUI state (`@State`, `@Binding`, `@Observable`, `@Environment`) and avoid unnecessary view models.\n- If the deployment target includes iOS 16 or earlier and cannot use the Observation API introduced in iOS 17, fall back to `ObservableObject` with `@StateObject` for root ownership, `@ObservedObject` for injected observation, and `@EnvironmentObject` only for truly shared app-level state.\n- Prefer composition; keep views small and focused.\n- Use async/await with `.task` and explicit loading/error states. For restart, cancellation, and debouncing guidance, read `references/async-state.md`.\n- Keep shared app services in `@Environment`, but prefer explicit initializer injection for feature-local dependencies and models. For root wiring patterns, read `references/app-wiring.md`.\n- Prefer the newest SwiftUI API that fits the deployment target and call out the minimum OS whenever a pattern depends on it.\n- Maintain existing legacy patterns only when editing legacy files.\n- Follow the project's formatter and style guide.\n- **Sheets**: Prefer `.sheet(item:)` over `.sheet(isPresented:)` when state represents a selected model. Avoid `if let` inside a sheet body. Sheets should own their actions and call `dismiss()` internally instead of forwarding `onCancel`/`onConfirm` closures.\n- **Scroll-driven reveals**: Prefer deriving a normalized progress value from scroll offset and driving the visual state from that single source of truth. Avoid parallel gesture state machines unless scroll alone cannot express the interaction.\n\n## State ownership summary\n\nUse the narrowest state tool that matches the ownership model:\n\n| Scenario | Preferred pattern |\n| --- | --- |\n| Local UI state owned by one view | `@State` |\n| Child mutates parent-owned value state | `@Binding` |\n| Root-owned reference model on iOS 17+ | `@State` with an `@Observable` type |\n| Child reads or mutates an injected `@Observable` model on iOS 17+ | Pass it explicitly as a stored property |\n| Shared app service or configuration | `@Environment(Type.self)` |\n| Legacy reference model on iOS 16 and earlier | `@StateObject` at the root, `@ObservedObject` when injected |\n\nChoose the ownership location first, then pick the wrapper. Do not introduce a reference model when plain value state is enough.\n\n## Cross-cutting references\n\n- `references/navigationstack.md`: navigation ownership, per-tab history, and enum routing.\n- `references/sheets.md`: centralized modal presentation and enum-driven sheets.\n- `references/deeplinks.md`: URL handling and routing external links into app destinations.\n- `references/app-wiring.md`: root dependency graph, environment usage, and app shell wiring.\n- `references/async-state.md`: `.task`, `.task(id:)`, cancellation, debouncing, and async UI state.\n- `references/previews.md`: `#Preview`, fixtures, mock environments, and isolated preview setup.\n- `references/performance.md`: stable identity, observation scope, lazy containers, and render-cost guardrails.\n\n## Anti-patterns\n\n- Giant views that mix layout, business logic, networking, routing, and formatting in one file.\n- Multiple boolean flags for mutually exclusive sheets, alerts, or navigation destinations.\n- Live service calls directly inside `body`-driven code paths instead of view lifecycle hooks or injected models/services.\n- Reaching for `AnyView` to work around type mismatches that should be solved with better composition.\n- Defaulting every shared dependency to `@EnvironmentObject` or a global router without a clear ownership reason.\n\n## Workflow for a new SwiftUI view\n\n1. Define the view's state, ownership location, and minimum OS assumptions before writing UI code.\n2. Identify which dependencies belong in `@Environment` and which should stay as explicit initializer inputs.\n3. Sketch the view hierarchy, routing model, and presentation points; extract repeated parts into subviews. For complex navigation, read `references/navigationstack.md`, `references/sheets.md`, or `references/deeplinks.md`. **Build and verify no compiler errors before proceeding.**\n4. Implement async loading with `.task` or `.task(id:)`, plus explicit loading and error states when needed. Read `references/async-state.md` when the work depends on changing inputs or cancellation.\n5. Add previews for the primary and secondary states, then add accessibility labels or identifiers when the UI is interactive. Read `references/previews.md` when the view needs fixtures or injected mock dependencies.\n6. Validate with a build: confirm no compiler errors, check that previews render without crashing, ensure state changes propagate correctly, and sanity-check that list identity and observation scope will not cause avoidable re-renders. Read `references/performance.md` if the screen is large, scroll-heavy, or frequently updated. For common SwiftUI compilation errors — missing `@State` annotations, ambiguous `ViewBuilder` closures, or mismatched generic types — resolve them before updating callsites. **If the build fails:** read the error message carefully, fix the identified issue, then rebuild before proceeding to the next step. If a preview crashes, isolate the offending subview, confirm its state initialisation is valid, and re-run the preview before continuing.\n\n## Component references\n\nUse `references/components-index.md` as the entry point. Each component reference should include:\n- Intent and best-fit scenarios.\n- Minimal usage pattern with local conventions.\n- Pitfalls and performance notes.\n- Paths to existing examples in the current repo.\n\n## Adding a new component reference\n\n- Create `references/<component>.md`.\n- Keep it short and actionable; link to concrete files in the current repo.\n- Update `references/components-index.md` with the new entry.\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["swiftui","patterns","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-swiftui-ui-patterns","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/swiftui-ui-patterns","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34460 github stars · SKILL.md body (7,466 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T06:51:57.698Z","embedding":null,"createdAt":"2026-04-18T21:45:44.661Z","updatedAt":"2026-04-22T06:51:57.698Z","lastSeenAt":"2026-04-22T06:51:57.698Z","tsv":"'1':681 '16':227,495 '17':239,459,475 '2':697 '3':712 '4':743 '5':771 '6':802 'access':782 'action':373,964 'ad':203,952 'add':167,772,781 'alert':624 'alon':415 'ambigu':860 'annot':859 'anti':601 'anti-pattern':600 'anyview':647 'api':235,314 'app':260,288,484,557,566 'app-level':259 'appli':5,92 'apptab':170 'around':650 'ask':1012 'assumpt':692 'async':13,44,576,745 'async/await':271 'avoid':217,362,408,835 'away':136 'back':241 'base':53,173,183 'belong':701 'best':931 'best-fit':930 'better':658 'bind':213,451 'bodi':368,633 'boolean':618 'boundari':1020 'build':143,735,806,874 'busi':608 'call':321,375,630 'callsit':871 'cancel':280,573,770 'cannot':231,416 'care':880 'caus':834 'central':541 'chang':767,819 'check':811,825 'child':444,465 'choos':50,112,178,505 'clarif':1014 'clear':672,987 'closest':89 'closur':383,862 'code':635,696 'common':853 'compil':739,809,855 'complex':728 'compon':36,48,115,181,915,924,955 'composit':264,659 'concret':967 'configur':487 'confirm':807,901 'contain':594 'content':128,135 'continu':914 'convent':94,939 'correct':821 'cost':598 'crash':816,896 'creat':27,957 'criteria':1023 'cross':527 'cross-cut':526 'current':950,971 'cut':528 'data':154 'debounc':282,574 'default':660 'defin':682 'depend':111,301,329,561,663,700,765,801 'deploy':223,318 'deriv':389 'describ':991 'destin':558,627 'detail':70 'direct':631 'dismiss':376 'drag':130 'drive':398 'driven':386,547,634 'earlier':229,497 'edit':338 'editor':71 'enough':525 'ensur':817 'entri':921,978 'enum':198,538,546 'enum-driven':545 'environ':107,215,291,488,563,583,703,1003 'environment-specif':1002 'environmentobject':254,665 'error':740,756,810,856,878 'everi':661 'exampl':77,947 'exclus':622 'exist':57,333,946 'expand':193 'expert':1008 'explicit':275,294,478,709,753 'express':417 'extern':554 'extract':722 'fail':875 'fall':240 'featur':61,299 'feature-loc':298 'file':340,616,968 'find':74 'first':189,509 'fit':316,932 'fix':881 'fixtur':581,797 'flag':619 'flow':32,155 'focus':148,269 'follow':120,207,341 'format':613 'formatt':345 'forward':380 'frequent':850 'general':204 'generic':865 'gestur':141,410 'giant':603 'global':668 'goal':56 'graph':562 'guardrail':599 'guid':348 'guidanc':40,122,283 'handl':551 'heavi':848 'hierarchi':716 'histori':536 'hook':641 'id':572,751 'ident':590,828 'identifi':59,698,785,883 'implement':140,744 'includ':225,927 'initi':295,710 'initialis':904 'inject':108,251,296,470,504,643,799 'input':711,768,1017 'insid':365,632 'instead':378,637 'intent':928 'interact':67,125,419,790 'intern':377 'introduc':236,516 'io':226,238,458,474,494 'isol':585,897 'ispres':355 'issu':884 'item':352 'keep':100,265,286,960 'label':783 'larg':845 'layout':607 'lazi':593 'legaci':334,339,490 'let':364 'level':261 'lifecycl':640 'limit':979 'link':555,965 'list':69,827 'live':628 'load':746,754 'loading/error':276 'local':93,102,300,436,938 'locat':508,688 'logic':609 'machin':412 'maintain':332 'manual':142 'match':429,988 'md':959 'messag':879 'minim':169,934 'minimum':324,690 'mismatch':652,864 'miss':857,1025 'mix':606 'mock':582,800 'modal':542 'model':68,220,303,361,432,456,472,492,519,718 'models/services':644 'modern':209 'multipl':617 'mutat':445,468 'mutual':621 'narrowest':425 'nativ':98,153 'navig':11,42,531,626,729 'navigationstack':165,191 'nearbi':76 'need':39,188,759,796 'network':610 'new':156,200,678,954,977 'newest':312 'next':180,891 'normal':391 'note':943 'observ':214,234,252,463,471,591,830 'observableobject':243 'observedobject':249,502 'offend':899 'offset':396 'oncancel':381 'onconfirm':382 'one':441,615 'os':325,691 'output':997 'own':439,448,454 'ownership':248,421,431,507,532,673,687 'parallel':409 'parent':447 'parent-own':446 'part':724 'pass':476 'path':636,944 'pattern':4,9,20,49,307,328,335,435,602,936 'per':534 'per-tab':533 'perform':942 'permiss':1018 'pick':511 'pitfal':940 'plain':521 'plus':752 'point':721,922 'possibl':104 'prefer':95,263,293,310,350,388,434 'present':543,720 'preview':46,580,586,773,813,895,912 'primari':66,134,776 'proceed':742,888 'progress':392 'project':58,157,343 'propag':820 'properti':482 'proven':6 'provid':176 'quick':21 're':837,909 're-rend':836 're-run':908 'reach':645 'read':87,137,284,308,466,730,760,791,839,876 'reason':674 'rebuild':886 'refactor':29 'refer':116,182,455,491,518,529,916,925,956,958 'references/app-wiring.md':161,309,559 'references/async-state.md':285,569,761 'references/components-index.md':118,918,974 'references/deeplinks.md':549,734 'references/navigationstack.md':530,731 'references/performance.md':588,840 'references/previews.md':579,792 'references/scroll-reveal.md':138 'references/sheets.md':540,732 'relev':114 'render':597,814,838 'render-cost':596 'repeat':723 'repo':80,951,972 'repres':358 'requir':1016 'resolv':867 'restart':279 'reusabl':16,34 'reveal':126,387 'review':1009 'rg':82 'root':247,305,453,501,560 'root-own':452 'rout':195,539,553,611,717 'router':669 'routerpath':172 'rule':205 'run':910 'safeti':1019 'saniti':824 'sanity-check':823 'scaffold':158 'scenario':433,933 'scope':592,831,990 'screen':17,31,63,201,843 'scroll':132,385,395,414,847 'scroll-driven':384 'scroll-heavi':846 'secondari':127,778 'select':360 'servic':289,485,629 'set':72 'setup':587 'share':110,258,287,483,662 'sheet':12,43,166,192,197,349,351,354,367,369,548,623 'shell':567 'short':962 'similar':85 'singl':404 'skeleton':177 'sketch':713 'skill':982 'skill-swiftui-ui-patterns' 'small':147,267 'solv':656 'sourc':405 'source-sickn33' 'specif':1004 'stabl':589 'start':22,159 'state':14,45,99,101,211,212,262,277,357,401,411,420,426,438,443,450,460,523,578,686,757,779,818,858,903 'stateobject':245,498 'stay':707 'step':892 'stop':1010 'store':481 'style':347 'substitut':1000 'subview':149,726,900 'success':1022 'summari':422 'swiftui':2,7,18,30,90,97,152,210,313,679,854 'swiftui-n':96,151 'swiftui-ui-pattern':1 'tab':73,535 'tabview':83,164,190 'target':224,319 'task':273,570,571,748,750,986 'test':1006 'tool':427 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'track':52 'treat':995 'truli':257 'truth':407 'type':464,651,866 'type.self':489 'ui':3,8,19,35,186,437,577,695,788 'unless':413 'unnecessari':218 'updat':851,870,973 'url':550 'usag':564,935 'use':25,106,208,232,270,423,917,980 'valid':803,906,1005 'valu':393,449,522 'verifi':737 'view':91,145,219,266,442,604,639,680,684,715,795 'viewbuild':861 'visual':400 'whenev':326 'wire':163,306,568 'without':670,815 'work':649,764 'workflow':675 'wrapper':513 'write':694","prices":[{"id":"2110344c-78f0-4e9e-bd01-129e3194898e","listingId":"3ceea42d-dba0-462b-84da-5adcbd844d42","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:45:44.661Z"}],"sources":[{"listingId":"3ceea42d-dba0-462b-84da-5adcbd844d42","source":"github","sourceId":"sickn33/antigravity-awesome-skills/swiftui-ui-patterns","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/swiftui-ui-patterns","isPrimary":false,"firstSeenAt":"2026-04-18T21:45:44.661Z","lastSeenAt":"2026-04-22T06:51:57.698Z"}],"details":{"listingId":"3ceea42d-dba0-462b-84da-5adcbd844d42","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"swiftui-ui-patterns","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34460,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-22T06:40:00Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"ea821a28253e2db0c52761df7a0774139ef479e6","skill_md_path":"skills/swiftui-ui-patterns/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/swiftui-ui-patterns"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"swiftui-ui-patterns","description":"Apply proven SwiftUI UI patterns for navigation, sheets, async state, and reusable screens."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/swiftui-ui-patterns"},"updatedAt":"2026-04-22T06:51:57.698Z"}}