# iPhone Duo — estado de la adaptación (Portfolio Journal 1.7.0) Fase 1, hecha con Xcode 27.0 / SDK iOS 27.0 (sin las APIs específicas de Duo de Xcode 27.1). Todo lo que se describe aquí funciona con size classes estándar: | Pantalla Duo | Size class | Cómo se comporta la app | |---|---|---| | Exterior 5.4" (vertical) | compact × regular | Igual que un iPhone: tab bar, stacks | | Exterior (horizontal) | compact × compact | Igual que un iPhone en horizontal | | Interior 7.6" (ambas orientaciones) | regular × regular | Layouts de dos columnas, sidebar/tab bar superior, inspector | ## Qué se ha adaptado ### Navegación (ContentView) - Un único `TabView` para todas las size classes. En iOS 18+ usa `.tabViewStyle(.sidebarAdaptable)`: tab bar en compacto, tab bar superior / sidebar en regular. Antes había dos jerarquías (`TabView` iPhone / `NavigationSplitView` iPad) y el cambio de size class las intercambiaba, perdiendo el estado; ahora abrir/cerrar el Duo conserva cada pestaña. - `@SceneStorage("selectedTab")` restaura la pestaña por escena. - Ningún `userInterfaceIdiom`, `UIScreen.main`, ni orientación: todo por `@Environment(\.horizontalSizeClass)`. ### Escenarios regular×regular (pantalla interior) 1. **Fuentes**: `NavigationSplitView` — lista de posiciones a la izquierda y detalle (rendimiento, gráfico, snapshots) a la derecha, a la vez. En compacto colapsa a stack; la selección es el único estado de navegación, así sobrevive al plegado. 2. **Diario**: `NavigationSplitView` — lista de meses + check-in mensual inline. 3. **Dashboard + Quick Update**: el check-in rápido se abre como `.inspector` (panel lateral) en ancho regular, de modo que los gráficos del dashboard siguen visibles mientras se teclean los valores; en compacto es un sheet. El dashboard usa masonry de 2/3 columnas según el ancho disponible (`GeometryReader`), que se recalcula al abrir/cerrar el inspector. 4. **Gráficos**: sidebar de tipos de gráfico (248 pt) + área de gráfico a todo el ancho, cabecera KPI y selector de periodo segmentado. Nuevo `chartHeightScale` (+35 % de alto en regular) para que el ancho extra se traduzca en más área de trazado; las etiquetas de eje ya eran más densas en regular. 5. **Bloqueo / privacidad**: `LAContext.biometryType` → "Desbloquear con Face ID / Touch ID / Optic ID"; icono y textos genéricos en 7 idiomas. ### Reglas de Apple aplicadas - Layout por size classes (regla 1), sin `UIScreen.main` (2), sin tamaños de pantalla fijos (3): las columnas usan `navigationSplitViewColumnWidth(min:ideal:max:)` e `inspectorColumnWidth`, y el contenido `maxWidth: .infinity`. - Navegación nativa: `TabView` sidebarAdaptable, `NavigationSplitView`, `.inspector`, sheets/popovers/alerts del sistema (4, 11). - Safe areas: se eliminó el `ignoresSafeArea(edges: .bottom)` del contenido interactivo de Gráficos; solo fondos decorativos (`AppBackground`) ignoran el safe area (5). - Orientaciones: iPhone vertical + horizontal, iPad las 4; sin `UIRequiresFullScreen`; `UIApplicationSupportsMultipleScenes = YES` (6). - Biometría por `biometryType` (7). - Estado persistente ante redimensionado: sin intercambio de jerarquías, `@SceneStorage`, ViewModels en `@StateObject` que sobreviven al cambio de size class (9). - Liquid Glass: barras del sistema automáticas al compilar con SDK 27; `glassEffect` en las etiquetas flotantes del Diario (iOS 26+, fallback material). ### Esquinas concéntricas (regla 8) No aplicada: ninguna tarjeta llega a sangre hasta la esquina de pantalla (todo va con padding dentro de `ScrollView`/`List`). Revisar en fase 2 si el edge-to-edge de 27.1 cambia esto. ## Qué queda para la fase 2 (Xcode 27.1) - `ArrangementView` / `ReservedRegion`: llegar al borde de la pantalla interior y respetar la región reservada (botones del sistema en Split View). - Probar en el simulador Duo (Device Hub) el plegado en caliente: comprobar que el inspector de Quick Update y las columnas de Fuentes/Diario se recomponen sin perder el texto tecleado. - Skill "App Resizability" y release notes con el edge-to-edge. - Traducir `fastlane/metadata/{de-DE,fr-*,it,ja,pt-*}/release_notes.txt` (solo en-* y es-* están actualizados). - Widgets: verificar tamaños en la pantalla interior cuando exista simulador. ## Verificado (16 sep 2026, Xcode 27.0) - `xcodebuild build` iOS (app + widget + extensión Quick Update) y watchOS (app + complicaciones): sin errores ni warnings de compilador. - 108/108 tests unitarios en iPhone 17 Pro. - `DuoLayoutUITests` en iPhone 17 Pro (compacto) y iPad mini A17 Pro (regular×regular): tab bar / tab bar superior, Fuentes y Diario en dos columnas, inspector de Quick Update (abre y cierra), gráficos con sidebar, vertical y horizontal. ## Cómo probarlo ```bash # Build (un simulador cada vez) xcodebuild -project PortfolioJournal.xcodeproj -scheme PortfolioJournal \ -destination 'platform=iOS Simulator,name=iPad mini (A17 Pro)' build # Recorrido con capturas (compacto vs regular×regular) xcodebuild test -project PortfolioJournal.xcodeproj -scheme PortfolioJournal \ -destination 'platform=iOS Simulator,name=iPhone 17 Pro' \ -only-testing:PortfolioJournalUITests/DuoLayoutUITests -resultBundlePath /tmp/duo-iphone.xcresult xcodebuild test ... -destination 'platform=iOS Simulator,name=iPad mini (A17 Pro)' \ -only-testing:PortfolioJournalUITests/DuoLayoutUITests -resultBundlePath /tmp/duo-ipad.xcresult xcrun xcresulttool export attachments --path /tmp/duo-ipad.xcresult --output-path /tmp/duo-ipad-png ``` La app arranca con datos de ejemplo y sin onboarding con el argumento `--screenshots`. iPad mini (A17 Pro) es el simulador más parecido a la pantalla interior del Duo (regular×regular en ambas orientaciones).