expo-duo

Verwenden beim Erstellen, Auditeren oder Reparieren einer Expo / React Native App für das iPhone Duo (Apples faltbares iPhone), inklusive vertikaler Rail, Safe-Area-Insets, NativeTabs, SplitView, ArrangementView, expo-hinge, reservierten Bereichen, Orientierungssperren und Testen von Duo-Posen lokal oder in EAS Workflows CI.

Was ist expo-duo?

Diese Skill-Anleitung (expo-duo) ist speziell für Entwickler:innen gedacht, die eine Expo/React Native App auf dem iPhone Duo – Apples faltbarem iPhone – zum Laufen bringen, auditieren oder korrigieren möchten. Sie fasst die vier Kernregeln zusammen: iOS die Navigation überlassen (per Stack und NativeTabs), SafeAreaView mit horizontalen Insets auf jedem Screen, Testen jeder Pose (gefaltet, offen, Split View) und gezieltes Tweaking nur wo nötig (ArrangementView, preferredPlacement, reservierte Bereiche, Hinge APIs, Abschalten der Rail). Der Schwerpunkt liegt auf Safe-Area-Bugs, Expo Router (Header in der Rail, SplitView, NativeTabs preferredPlacement), den Zusatz-APIs ArrangementView, useReservedRegions(), expo-hinge und useVerticalBarEdgeIOS() sowie Orientierungssperren. Die Anleitung enthält eine Test-Checkliste, einen Audit-Workflow und CI-Anweisungen (expo:eas-workflows) für den Duo-Simulator in Device Hub (Xcode 27.1) und EAS Workflows. Häufige Fehler werden aufgelistet und korrigiert.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Andrewi89/Stride-skills/tree/HEAD/plugins/design/skills/expo-duo

Installed? Explore more Produktivität & Zusammenarbeit skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Expo auf iPhone Duo

Quelle: https://expo.dev/blog/supporting-iphone-duo (Expo SDK 58). Designregeln befinden sich in apple-design-duo; dieser Skill ist die Expo- und React-Native-Implementierungsebene. CI-Pipeline-Hintergrund: https://docs.expo.dev/tutorial/cicd/introduction/ und der Skill expo:eas-workflows.

Anforderungen

  • Expo SDK 58 (zielt auf iOS 27) und Xcode 27.1 (iOS 27.1 Laufzeit plus iPhone Duo Simulator).
  • EAS Build-Image: sdk-58 oder latest.
  • Xcode 27 ersetzt Simulator.app durch Device Hub (Xcode > Open Developer Tool > Device Hub). Es gibt ein 3D-Duo, das gefaltet, gedreht und der Scharnierwinkel eingestellt werden kann.

Gedankenmodell

Gefaltet = kompakte Breite, offen = reguläre Breite. Layouts verbreitern sich, Designs werden nie umgeschaltet. Gleiche Funktionen und Zustände auf beiden Seiten. In buchartigen Posen verschiebt iOS die Statusleiste, Tab-Leiste und Symbolleiste in eine vertikale Leiste (Rail) an einer Kante.

Die vier Regeln

  1. iOS die Navigation zeichnen lassen. Verwende Expo Router Stack und NativeTabs. Benutzerdefinierte JS-Header und <TabList> sind nicht rail-bewusst (SDK 58 bietet nur minimale Kompatibilität) und <TabList> kann nicht in die Rail gesetzt werden.
  2. SafeAreaView (react-native-safe-area-context) auf jedem Bildschirm, horizontale Insets inklusive.
  3. Jede Pose testen. Falten, entfalten, drehen, Split View.
  4. Nur wo nötig anpassen: ArrangementView, preferredPlacement, reservierte Bereiche, Hinge-APIs oder Deaktivieren der Rail.

Safe Areas (hier treten die meisten Fehler auf)

  • Die Rail benötigt einen 84pt Inset auf der linken oder rechten Seite.
  • Wickle Scroll-Inhalte in SafeAreaView edges={['left','right']}, nicht in den ScrollView, damit Hintergründe randlos laufen. Setze contentInsetAdjustmentBehavior="automatic" auf dem ScrollView (RN-Patch #59194 sollte dies allein ausreichend machen).
  • Horizontale Karussells: Fügen selbst End-Padding hinzu.
  • Schwebende Buttons und Toasts: right: insets.right + 16. Bei RTL beide left und right lesen.
  • Innerhalb von NativeTabs beinhaltet insets.bottom die Tab-Leiste nur, wenn sie unten verläuft. Niemals eine feste Tab-Leisten-Höhe hinzufügen.
  • Den Content-Container mit Insets polstern, nicht die Root-Ansicht.
  • Lies useWindowDimensions zur Renderzeit. Das linke Split-View-Fenster ist 469pt breit.

Expo Router

  • Header-Buttons in der Rail stapeln sich in einer Spalte, Zurück oder Schließen zuerst. Nur-Text-Elemente bleiben horizontal. Benutzerdefinierte Ansichten sind ausgeschlossen.
  • Eine Live Activity im Dynamic Island kann Symbolleisten in den Überlaufbereich schieben. Nicht dagegen ankämpfen.
  • <SplitView> umschließt die systemeigene Split-View: eine Spalte gefaltet, zwei offen, faltbewusst. Experimentell in SDK 58.
  • NativeTabs preferredPlacement: 'sidebar' | 'tabBar' | 'automatic'. Gilt auf dem offenen Display im Querformat.

Zusätzliche APIs

BedarfAPI
Zweispaltiger Inhalt (nur iOS 27.1, ältere Versionen rendern Kinder ohne Container)ArrangementView von @expo/ui/swift-ui, innerhalb eines Host, mit ArrangementView.Primary und .Secondary. Styling mit arrangementViewStyle('split' | 'overlay'), splitArrangementLayoutSize, overlayArrangementEdge. Modifiers von @expo/ui/swift-ui/modifiers.
Falt- und Verdeckungsrahmennpx expo install react-native-reserved-regions, dann gibt useReservedRegions() { kind: 'division' | 'occlusion', frame } in Punkten zurück. Gut für benutzerdefinierte Spielsteuerungen und gleichmäßige Spaltenraster. Nicht verwenden, um Inhalte an der Falte zu teilen – dafür ArrangementView verwenden.
Scharnierwinkel und -statusnpx expo install expo-hinge. useHinge(), getHinge(), addHingeListener(). Status: closed, partiallyOpen, fullyOpen, unknown. Der SwiftUI-Modifier onHingeChange kann über useWorkletCallback auf dem UI-Thread ausgeführt werden. Funktioniert mit Reanimated und Android 11+ Foldables.
Rail-KanteuseVerticalBarEdgeIOS() gibt 'leading', 'trailing' oder null zurück. Kein Duo-Detektor (offenes Hochformat gibt null zurück).
Rail deaktivieren<StatusBar verticalBarBehaviorIOS="disabled" /> (mapped auf preferredVerticalBarBehavior). Nur für Videoplayer oder Taschenrechner-artige Bildschirme, und die Wahl pro Bildschirm stabil halten.

Orientierung

Unter iOS 27 sind Orientierungssperren Präferenzen in veränderbaren Kontexten. lockAsync kann verweigert werden und requireFullScreen wählt nicht mehr ab. Das Sperren auf Hoch- oder Querformat auf Duo funktioniert nur, wenn die App den Bildschirm durch Posenänderungen hindurch füllt.

Bekannte Grenzen

  • StandBy ist im Duo-Simulator nicht verfügbar, und die meisten App-Erweiterungen sind im Simulator von Xcode 27.1 nicht verfügbar. Teste Widgets und Erweiterungen auf einem Gerät.
  • expo-app-intents (Alpha, ebenfalls SDK 58) legt Aktionen für Siri, Shortcuts und Spotlight frei. Einige Schemas benötigen ein neueres iOS als ihre Domäne (.mail.openDraft benötigt iOS 27). Unabhängig vom Layout.

Test-Checkliste

  • Gefaltet: Nichts Wichtiges unter der Rail, Buttons reagieren.
  • Offen: Layout schaltet keine Designs um, nichts unter der Rail, Hochformat-Leisten kehren nach oben und unten zurück.
  • Teilweise offen: Nichts Wesentliches in der Falte, Blätter und Popover landen auf einer Seite.
  • Split View: Inhalt frei von der Rail (linke Kante des linken Fensters).
  • Falten bei mittigem Bildschirm: Scroll-Position, Zustand und Aktionen bleiben erhalten.
  • Standard-iPhone: Nichts ändert sich.

Audit-Workflow

  1. SDK 58 bestätigen und neu bauen.
  2. Nach benutzerdefinierten Headern oder Tab-Leisten suchen (grep headerShown: false plus handgebaute Leisten, TabList) und zu Stack und NativeTabs migrieren.
  3. Nach hartcodierten top, bottom, left, right Offsets, festen Tab-Leisten-Höhen und Root-Level-Padding suchen (grep). Durch Insets ersetzen.
  4. Karussells, FABs und Toasts gemäß der Safe-Area-Liste prüfen.
  5. Zweispaltige Bildschirme auswählen: SplitView oder ArrangementView.
  6. Pro Bildschirm entscheiden, ob reservierte Bereiche oder der Hinge nur dann benötigt werden, wenn ein benutzerdefiniertes Layout sie wirklich braucht.
  7. Im Device Hub verifizieren, dann in CI (siehe unten).

CI: Auf dem Duo-Simulator ausführen

Den Skill expo:eas-workflows verwenden (zuerst das Live-Schema abrufen, keine Job-Parameter raten). Eine sinnvolle Form aus dem CI/CD-Tutorial: PR-getriggerter Simulator-Build auf dem Image sdk-58 oder latest, optional Maestro E2E, dann fingerprint-basierte Wahl zwischen nativen Build und EAS Update für die Produktion. Mit npx -y eas-cli@latest workflow:validate .eas/workflows/<file>.yml --non-interactive validieren. Workflows verbrauchen bezahlte EAS-Minuten.

Häufige Fehler

FehlerKorrektur
ScrollView mit Insets polsternSafeAreaView darum, contentInsetAdjustmentBehavior="automatic"
Feste Tab-Leisten-Höhe im Paddinginsets.bottom aus der Safe Area verwenden
useVerticalBarEdgeIOS() zur Duo-Erkennung verwendenEs ist nur die Rail-Kante, null im offenen Hochformat
Inhalte an der Falte mit reservierten Bereichen teilenArrangementView oder SplitView
Handgebaute JS-Header oder Tab-LeisteStack und NativeTabs
Schwebender Button bei right: 16right: insets.right + 16
Annahme, dass lockAsync immer erfolgreich istAls Präferenz behandeln und den Bildschirm füllen
Nur auf einem Standard-iPhone testenDevice Hub, jede Pose

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Verwandte Skills