e9e3e5da66
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F1u4K16xy7eQVtgsYNZ9Vn
104 lines
5.7 KiB
Markdown
104 lines
5.7 KiB
Markdown
# 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).
|