Adapts and reviews SwiftUI apps for iPhone Duo and continuously changing window sizes. Use when supporting the foldable iPhone Duo, hinge or fold layout, ArrangementView, reserved regions, scene accessories, outer or inner display, NavigationSplitView, adaptive TabView, ViewThatFits, AnyLayout, or when replacing UIDevice / UIScreen / idiom / orientation layout branches.
Do not design a separate “Duo version” of the app.
Start with an adaptive SwiftUI interface that works across continuously changing widths and heights. Add Duo-specific behavior only when the fold, hinge, second display, or vertical system bars materially improve the experience.
The target is not “Make this app support iPhone Duo.” The target is:
Make this app excellent at every size, then use Duo's unique hardware where it creates additional value.
Before reviewing or changing layout, read the full rulebook: reference.md.
When to use
User asks to support iPhone Duo, a foldable iPhone, hinge, fold, or two displays.
User asks for adaptive SwiftUI layout across compact → wide, including multitasking.
Code uses UIDevice, UIScreen.main.bounds, idiom, orientation, isDuo, or isFolded for layout.
Work involves ArrangementView, reserved regions, onHingeChange, or scene accessories.
Prefer NavigationSplitView for collection → selection → detail. Prefer adaptive TabView (.sidebarAdaptable) over a hand-built sidebar.
Prefer system .toolbar / ToolbarItem / ToolbarOverflowMenu so bars can become vertical.
Keep one view hierarchy; hoist navigation, scroll, selection, editor, and playback state above layout.
Use extra width for panes, inspectors, columns, and persistent navigation — not longer text lines. Cap readable content (e.g. .frame(maxWidth: 700)).
Move fold-sensitive controls locally. Do not rebuild the whole screen because a reserved region appeared.
Use ArrangementView only for one two-part experience (player + playlist, editor + inspector). Do not use it as app navigation.
Use onHingeChange / hinge angle only for physical interaction. Layout reacts to space. Interaction may react to hinge state.
For the outer display, use scene accessories. Do not target innerDisplay / outerDisplay as independent canvases.
3) Untestable Duo behavior
Until the project can be tested with the iPhone Duo simulator in Xcode 27.1:
The agent may:
improve general adaptability
remove device assumptions
adopt standard adaptive containers
prepare code boundaries for Duo-specific APIs
identify likely fold-sensitive UI
The agent should avoid:
hardcoding predicted hinge coordinates
guessing exact Duo dimensions
adding untested Duo-only layout branches
restructuring working screens around assumptions
If Duo-specific behavior cannot yet be verified in the simulator, prefer preparation over speculative implementation.
Agent decision tree
When reviewing a SwiftUI screen, evaluate it in this order.
Does the layout work across continuously changing widths? If no: fix the general adaptive layout first.
Is navigation manually switching between phone and tablet implementations? If yes: investigate NavigationSplitView, adaptive TabView, or another system navigation container.
Are there fixed widths or screen-size assumptions? If yes: replace them with container-relative layout where possible.
Does the wide layout simply stretch? If yes: look for a sidebar, detail pane, inspector, additional columns, or supplementary content.
Could important content intersect the fold? If yes: use reserved-region-aware positioning.
Are two related views being manually rearranged across layouts? If yes: evaluate ArrangementView, ViewThatFits, or AnyLayout.
Is there a custom toolbar or tab bar? If yes: determine whether SwiftUI system bars can replace it and adapt vertically.
Does the requested behavior genuinely depend on physical hinge position? If no: do not use the hinge API. If yes: use onHingeChange and hinge state/angle.
Would the outer display provide useful supplementary information? If yes: evaluate a scene accessory. Do not manually target a second screen.
Agent rules
These are strict. Full explanations and code are in reference.md.
When encountering device-specific layout logic, first attempt to replace it with layout behavior based on available container space.
Prefer semantic adaptive containers over manual breakpoints. Order: system navigation/container → adaptive grid → ViewThatFits → size classes → exact geometry last.
If a screen contains master/detail navigation, strongly prefer NavigationSplitView over a manually constructed HStack sidebar.
Do not stretch narrow interfaces indefinitely. Use extra space to increase information density or introduce complementary panes.
If repeated content appears in a grid, prefer minimum-item-width-driven adaptive columns (GridItem(.adaptive(minimum:))).
Use ViewThatFits when the question is “which arrangement fits?” rather than “which device am I on?”
Prefer changing layout containers (AnyLayout) over conditionally rebuilding separate view hierarchies.
Never use UIScreen.main.bounds for SwiftUI layout unless there is an exceptional non-layout requirement.
Avoid placing important interactive or semantic content across an active division region. Decorative backgrounds and scrolling content may usually cross the fold.
Respond to fold interference locally before making a global structural change.
Use ArrangementView only when the two views form one adaptive experience; do not substitute it for app navigation.
Before creating a custom toolbar, verify that the design cannot be expressed with SwiftUI's toolbar APIs.
Primary toolbar actions must remain visible; secondary actions may move into overflow as available bar space decreases.
If tabs represent primary app sections and the wide layout benefits from persistent navigation, prefer SwiftUI's adaptive sidebar system.
Never manually mirror one safe-area inset onto another edge. Duo safe areas can be asymmetric.
Treat the fold like the spine of a book: backgrounds may span it; precise content should not.
Layout reacts to space. Interaction may react to hinge state. Do not use hinge.angle for sidebar, columns, grid count, or navigation collapse.
Use scene accessories for intentionally secondary display content; keep the main experience attached to the primary scene.
A layout transition must not become an application-state transition.
Every expansive layout must have a graceful path back through intermediate widths to compact presentation. Unfolded does not mean wide app.
More available width does not imply wider text lines.
Wide layouts should reveal more useful structure, not just more whitespace.
Optimize for reach and grouping, not maximum geometric distribution.
Always complete Tier 1 before proposing Tier 2 or Tier 3 changes.
If Duo-specific behavior cannot yet be verified in the simulator, prefer preparation over speculative implementation.
Code-review red flags
Flag these when used for ordinary layout decisions:
UIScreen.main.bounds
UIDevice.current.userInterfaceIdiom == .pad
if orientation == .landscape
if isIPhoneDuo
if isFolded { ... }
Also flag:
fixed large frames
hardcoded sidebar widths
fixed grid column counts
custom fake toolbars
content centered directly across the fold
duplicated compact and expanded state
layouts tested only at two widths
excessive full-width text
controls placed outside safe areas
Preferred replacements are in reference.md.
Review checklist
No if isDuo / idiom / orientation / UIScreen layout branches
Layout follows container space across narrow → intermediate → wide
List/detail uses NavigationSplitView with preserved selection
Grids use GridItem(.adaptive(minimum:)) rather than fixed column counts
Local rearrangements use ViewThatFits or AnyLayout, not duplicate hierarchies
System toolbars/tabs used; items work horizontally and vertically
Important controls stay in (possibly asymmetric) safe areas
Critical content is not centered on the fold
State (nav, scroll, selection, editors, playback) survives fold/display changes
Hinge APIs used only for physical interaction
Second display uses scene accessories, not manual display targeting
Tier 2/3 APIs added only after Tier 1, and only when testable
Additional resources
Full 25 rules, API sketches, and before/after transformations: reference.md
1---2name: swiftui-iphone-duo3description: Adapts and reviews SwiftUI apps for iPhone Duo and continuously changing window sizes. Use when supporting the foldable iPhone Duo, hinge or fold layout, ArrangementView, reserved regions, scene accessories, outer or inner display, NavigationSplitView, adaptive TabView, ViewThatFits, AnyLayout, or when replacing UIDevice / UIScreen / idiom / orientation layout branches.4---56# SwiftUI iPhone Duo78**Do not design a separate “Duo version” of the app.**910Start with an adaptive SwiftUI interface that works across continuously changing widths and heights. Add Duo-specific behavior only when the fold, hinge, second display, or vertical system bars materially improve the experience.1112The target is not “Make this app support iPhone Duo.” The target is:1314**Make this app excellent at every size, then use Duo's unique hardware where it creates additional value.**1516Before reviewing or changing layout, read the full rulebook: [reference.md](reference.md).1718## When to use1920- User asks to support **iPhone Duo**, a **foldable iPhone**, **hinge**, **fold**, or **two displays**.21- User asks for **adaptive SwiftUI layout** across compact → wide, including **multitasking**.22- Code uses `UIDevice`, `UIScreen.main.bounds`, idiom, orientation, `isDuo`, or `isFolded` for layout.23- Work involves `ArrangementView`, reserved regions, `onHingeChange`, or scene accessories.2425## Related skills2627| Skill | When to load |28|-------|--------------|29| **swiftui-whats-new-27** | Toolbar overflow, `visibilityPriority`, `ToolbarOverflowMenu`, `.topBarPinnedTrailing` |30| **swiftui-specialist** | Broader SwiftUI layout and navigation correctness |31| **swiftui-liquid-glass** | System bars and glass chrome on iOS 26+ |3233---3435## Optimization order36371. Adaptive layout382. Adaptive navigation393. Adaptive toolbars and tabs404. Fold-safe positioning415. Duo-specific arrangements426. Hinge-driven interactions437. Second-display experiences4445## Progressive API tiers4647Classify every change before writing code. **Always complete Tier 1 before proposing Tier 2 or Tier 3.**4849**Tier 1 — Universal adaptive improvements** (do these first):5051```text52NavigationSplitView53adaptive TabView54adaptive grids55ViewThatFits56AnyLayout57size classes58container-relative sizing59system toolbars60safe-area correctness61```6263These benefit all Apple platforms and window sizes.6465**Tier 2 — Duo-aware layout** (only when needed):6667```text68Reserved Regions69ArrangementView70vertical toolbar behavior71Duo-specific safe-area handling72```7374**Tier 3 — Duo-exclusive experiences** (only when the product benefits):7576```text77onHingeChange78hinge angle79scene accessories80multi-display interactions81multi-scene Duo workflows82```8384---8586## Workflow8788Copy and track progress:8990```91- [ ] 1. Read reference.md92- [ ] 2. Review screens with the decision tree93- [ ] 3. Flag red-flag patterns with file evidence94- [ ] 4. Classify each change as Tier 1 / 2 / 395- [ ] 5. Implement Tier 1 first96- [ ] 6. Apply Tier 2/3 only when space-based layout is insufficient97- [ ] 7. Keep state above adaptive layout; verify continuity across widths98```99100### 1) Review existing UI101102Walk every SwiftUI screen with the decision tree below. Flag:103104- Device identity used as a layout switch (`UIDevice`, idiom, model, `isDuo`, `isFolded`)105- `UIScreen.main.bounds` or orientation used for ordinary layout106- Fixed column counts, hardcoded sidebar widths, arbitrary `if width > N`107- Separate compact vs expanded view hierarchies with duplicated state108- Custom toolbars / tab bars that cannot move to a vertical edge109- Critical content that would sit on the fold110- Wide layouts that only stretch instead of exposing hierarchy111- Hinge angle used to decide sidebar, columns, or navigation112113### 2) Implement or refactor1141151. Replace device checks with container space: size classes, `ViewThatFits`, `AnyLayout`, adaptive grids, `containerRelativeFrame` / `onGeometryChange`.1162. Prefer `NavigationSplitView` for collection → selection → detail. Prefer adaptive `TabView` (`.sidebarAdaptable`) over a hand-built sidebar.1173. Prefer system `.toolbar` / `ToolbarItem` / `ToolbarOverflowMenu` so bars can become vertical.1184. Keep one view hierarchy; hoist navigation, scroll, selection, editor, and playback state above layout.1195. Use extra width for panes, inspectors, columns, and persistent navigation — not longer text lines. Cap readable content (e.g. `.frame(maxWidth: 700)`).1206. Move fold-sensitive controls locally. Do not rebuild the whole screen because a reserved region appeared.1217. Use `ArrangementView` only for one two-part experience (player + playlist, editor + inspector). Do not use it as app navigation.1228. Use `onHingeChange` / hinge angle only for physical interaction. **Layout reacts to space. Interaction may react to hinge state.**1239. For the outer display, use scene accessories. Do not target `innerDisplay` / `outerDisplay` as independent canvases.124125### 3) Untestable Duo behavior126127Until the project can be tested with the iPhone Duo simulator in Xcode 27.1:128129The agent **may**:130131- improve general adaptability132- remove device assumptions133- adopt standard adaptive containers134- prepare code boundaries for Duo-specific APIs135- identify likely fold-sensitive UI136137The agent **should avoid**:138139- hardcoding predicted hinge coordinates140- guessing exact Duo dimensions141- adding untested Duo-only layout branches142- restructuring working screens around assumptions143144**If Duo-specific behavior cannot yet be verified in the simulator, prefer preparation over speculative implementation.**145146---147148## Agent decision tree149150When reviewing a SwiftUI screen, evaluate it in this order.1511521. **Does the layout work across continuously changing widths?** 153 If no: fix the general adaptive layout first.1541552. **Is navigation manually switching between phone and tablet implementations?** 156 If yes: investigate `NavigationSplitView`, adaptive `TabView`, or another system navigation container.1571583. **Are there fixed widths or screen-size assumptions?** 159 If yes: replace them with container-relative layout where possible.1601614. **Does the wide layout simply stretch?** 162 If yes: look for a sidebar, detail pane, inspector, additional columns, or supplementary content.1631645. **Could important content intersect the fold?** 165 If yes: use reserved-region-aware positioning.1661676. **Are two related views being manually rearranged across layouts?** 168 If yes: evaluate `ArrangementView`, `ViewThatFits`, or `AnyLayout`.1691707. **Is there a custom toolbar or tab bar?** 171 If yes: determine whether SwiftUI system bars can replace it and adapt vertically.1721738. **Does the requested behavior genuinely depend on physical hinge position?** 174 If no: do not use the hinge API. 175 If yes: use `onHingeChange` and hinge state/angle.1761779. **Would the outer display provide useful supplementary information?** 178 If yes: evaluate a scene accessory. Do not manually target a second screen.179180---181182## Agent rules183184These are strict. Full explanations and code are in [reference.md](reference.md).1851861. When encountering device-specific layout logic, first attempt to replace it with layout behavior based on available container space.1872. Prefer semantic adaptive containers over manual breakpoints. Order: system navigation/container → adaptive grid → `ViewThatFits` → size classes → exact geometry last.1883. If a screen contains master/detail navigation, strongly prefer `NavigationSplitView` over a manually constructed `HStack` sidebar.1894. Do not stretch narrow interfaces indefinitely. Use extra space to increase information density or introduce complementary panes.1905. If repeated content appears in a grid, prefer minimum-item-width-driven adaptive columns (`GridItem(.adaptive(minimum:))`).1916. Use `ViewThatFits` when the question is “which arrangement fits?” rather than “which device am I on?”1927. Prefer changing layout containers (`AnyLayout`) over conditionally rebuilding separate view hierarchies.1938. Never use `UIScreen.main.bounds` for SwiftUI layout unless there is an exceptional non-layout requirement.1949. Avoid placing important interactive or semantic content across an active division region. Decorative backgrounds and scrolling content may usually cross the fold.19510. Respond to fold interference locally before making a global structural change.19611. Use `ArrangementView` only when the two views form one adaptive experience; do not substitute it for app navigation.19712. Before creating a custom toolbar, verify that the design cannot be expressed with SwiftUI's toolbar APIs.19813. Primary toolbar actions must remain visible; secondary actions may move into overflow as available bar space decreases.19914. If tabs represent primary app sections and the wide layout benefits from persistent navigation, prefer SwiftUI's adaptive sidebar system.20015. Never manually mirror one safe-area inset onto another edge. Duo safe areas can be asymmetric.20116. Treat the fold like the spine of a book: backgrounds may span it; precise content should not.20217. Layout reacts to space. Interaction may react to hinge state. Do not use `hinge.angle` for sidebar, columns, grid count, or navigation collapse.20318. Use scene accessories for intentionally secondary display content; keep the main experience attached to the primary scene.20419. A layout transition must not become an application-state transition.20520. Every expansive layout must have a graceful path back through intermediate widths to compact presentation. Unfolded does not mean wide app.20621. More available width does not imply wider text lines.20722. Wide layouts should reveal more useful structure, not just more whitespace.20823. Optimize for reach and grouping, not maximum geometric distribution.20924. Always complete Tier 1 before proposing Tier 2 or Tier 3 changes.21025. If Duo-specific behavior cannot yet be verified in the simulator, prefer preparation over speculative implementation.211212---213214## Code-review red flags215216Flag these when used for ordinary layout decisions:217218```swift219UIScreen.main.bounds220UIDevice.current.userInterfaceIdiom == .pad221if orientation == .landscape222if isIPhoneDuo223if isFolded { ... }224```225226Also flag:227228- fixed large frames229- hardcoded sidebar widths230- fixed grid column counts231- custom fake toolbars232- content centered directly across the fold233- duplicated compact and expanded state234- layouts tested only at two widths235- excessive full-width text236- controls placed outside safe areas237238Preferred replacements are in [reference.md](reference.md#preferred-transformation-examples).239240---241242## Review checklist243244- [ ] No `if isDuo` / idiom / orientation / `UIScreen` layout branches245- [ ] Layout follows container space across narrow → intermediate → wide246- [ ] List/detail uses `NavigationSplitView` with preserved selection247- [ ] Grids use `GridItem(.adaptive(minimum:))` rather than fixed column counts248- [ ] Local rearrangements use `ViewThatFits` or `AnyLayout`, not duplicate hierarchies249- [ ] Wide layout exposes hierarchy (sidebar, detail, inspector, columns) instead of stretching250- [ ] Readable content has a maximum width251- [ ] System toolbars/tabs used; items work horizontally and vertically252- [ ] Important controls stay in (possibly asymmetric) safe areas253- [ ] Critical content is not centered on the fold254- [ ] State (nav, scroll, selection, editors, playback) survives fold/display changes255- [ ] Hinge APIs used only for physical interaction256- [ ] Second display uses scene accessories, not manual display targeting257- [ ] Tier 2/3 APIs added only after Tier 1, and only when testable258259---260261## Additional resources262263- Full 25 rules, API sketches, and before/after transformations: [reference.md](reference.md)
Run npx skillmds@latest add flowritescode/swiftui-iphone-duo in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Adapts and reviews SwiftUI apps for iPhone Duo and continuously changing window sizes. Use when supporting the foldable iPhone Duo, hinge or fold layout, ArrangementView, reserved regions, scene accessories, outer or inner display, NavigationSplitView, adaptive TabView, ViewThatFits, AnyLayout, or when replacing UIDevice / UIScreen / idiom / orientation layout branches. It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
flowritescode (@flowritescode) published this skill. Their other Agent Skills are listed on their SkillMD profile.