Una vista modal parece una pieza bastante resuelta de cualquier aplicación: se presenta, permite completar una tarea y se cierra. En iPhone Duo hay otra variable que revisar: el espacio disponible cambia al abrir, girar o plegar el dispositivo. Una presentación que resulta cómoda sobre una pantalla plana puede situar sus acciones justo en la zona curvada cuando el usuario cambia de postura.
Apple explica en Design for iPhone Duo que las hojas del sistema adaptan su tamaño, posición y barras de herramientas. En la pantalla exterior pueden mostrar los controles en una barra vertical; en la interior utilizan barras horizontales. Al plegar parcialmente el dispositivo, pueden desplazarse para evitar quedar apoyadas sobre el pliegue. La presentación tiene su propio contexto: la orientación de sus controles no tiene por qué coincidir con la de la aplicación situada detrás.
Evitar el pliegue tampoco significa prohibir que cualquier contenido lo atraviese. Apple distingue los elementos interactivos del contenido desplazable: conviene mantener las acciones alejadas de la zona central, mientras que una superficie con desplazamiento puede continuar por ella. Este comportamiento de adaptación está integrado en componentes del sistema. Por eso, antes de introducir coordenadas especiales y cálculos complejos para un dispositivo, merece la pena comprobar qué resuelve ya la presentación nativa.
Podemos partir de una pantalla de ayuda para una aplicación de astronomía. El usuario consulta unas indicaciones para preparar una observación y después cierra la vista. La presentación sigue usando el conocido modificador .sheet: un booleano controla su visibilidad y el bloque construye su contenido.
import SwiftUI
struct ObservationView: View {
@State private var showsGuide = false
var body: some View {
Button("Preparar la observación", systemImage: "moon.stars") {
showsGuide = true
}
.sheet(isPresented: $showsGuide) {
ObservationGuide()
}
}
}
struct ObservationGuide: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
NavigationStack {
ScrollView {
VStack(alignment: .leading, spacing: 20) {
Text("Antes de empezar")
.font(.title2.bold())
Text("Busca un lugar con poca iluminación artificial.")
Text("Deja que tus ojos se adapten a la oscuridad.")
Text("Comprueba la nubosidad antes de montar el equipo.")
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
}
.navigationTitle("Guía de observación")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cerrar", systemImage: "xmark") {
dismiss()
}
}
}
}
}
}
Aquí importa dónde se obtiene dismiss. La propiedad está dentro de ObservationGuide, que pertenece a la jerarquía presentada. La documentación de Apple sobre dismiss señala que esta acción depende del entorno desde el que se lee. Obtenerla en la pantalla que abre la vista y esperar que cierre esa presentación puede producir un resultado distinto del esperado. Separar ambas vistas deja claro qué presentación estamos cerrando.
La guía solo tiene una acción en su barra de herramientas. Reservar una franja lateral completa para ese botón puede restar espacio útil al texto. En Raise the bar with iPhone Duo, Apple contempla precisamente este caso y muestra cómo desactivar la barra vertical mediante .toolbarVerticalBehavior(.disabled).
NavigationStack {
ScrollView {
// Contenido de la guía
}
.navigationTitle("Guía de observación")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cerrar", systemImage: "xmark") {
dismiss()
}
}
}
.toolbarVerticalBehavior(.disabled)
}
Este fragmento sustituye al NavigationStack del ejemplo anterior y requiere un SDK que incluya la nueva API presentada para iPhone Duo. El modificador se aplica al contenido dentro del contenedor de navegación. Desactiva el comportamiento vertical de la barra; no es una API para elegir la posición de la vista ni para controlar su relación con el pliegue. Si la aplicación mantiene compatibilidad con sistemas anteriores, hay que respetar la disponibilidad que declare el SDK utilizado.
En una pantalla con varias acciones, conservar el comportamiento adaptativo puede ser más útil. Apple recomienda utilizar las barras gestionadas por los contenedores del sistema y proporcionar tanto el título como el símbolo de cada acción. Así el sistema dispone de información para representarla en distintos espacios. La decisión de desactivar la barra debería responder al contenido concreto de esa vista.
También conviene separar la altura de la presentación de su posición. presentationDetents permite declarar las alturas entre las que puede moverse una vista, por ejemplo .medium y .large. Es una configuración diferente de la barra vertical. Añadir esos tamaños no expresa la intención de colocar los controles a un lado del pliegue.
Para esta guía, mi primera prueba sería abrirla con el dispositivo cerrado y mantenerla visible mientras cambia de postura. Comprobaría que el texto sigue siendo legible, que se puede llegar al último párrafo y que el botón de cerrar continúa siendo fácil de localizar. Después repetiría el recorrido con tamaños grandes de Dynamic Type. Una captura correcta en una sola posición dice poco sobre una interfaz que puede cambiar mientras se utiliza.
Si la vista incluyera un formulario, añadiría otra prueba: escribir un valor, mostrar el teclado y cambiar de postura sin cerrar la presentación. El criterio sería conservar los datos introducidos y permitir continuar la tarea. No conviene reconstruir el flujo mediante una vista diferente para cada posición del dispositivo si eso complica la conservación del estado o altera innecesariamente la navegación.
La adaptación empieza por una presentación nativa, contenido flexible y acciones con un propósito claro. A partir de ahí, la revisión debe centrarse en problemas observables: texto recortado, controles difíciles de alcanzar o espacio desaprovechado. En una vista informativa con un único botón, desactivar la barra vertical puede ser un ajuste pequeño y útil; en una presentación más compleja, el comportamiento del sistema ofrece un buen punto de partida para mantener la tarea accesible durante los cambios de postura.