Una pantalla de recetas puede mostrar los ingredientes junto a los pasos de preparación. En una pantalla estrecha encaja mejor colocar unos debajo de otros; al abrir un dispositivo plegable (el iPhone Duo), podemos aprovechar dos columnas. Si además queda parcialmente plegado, interesa mantener el contenido a ambos lados de la bisagra.
Con iOS 27.1, SwiftUI incorpora ArrangementView para organizar dos vistas según el espacio y las condiciones del dispositivo. Declaramos el contenido principal y el secundario, y elegimos cómo se relacionan.
Repartir el espacio con split
El estilo predeterminado, .automatic, se resuelve como .split: cada vista recibe una parte del área disponible. Podemos indicarlo explícitamente para que la intención quede clara.
import SwiftUI
@available(iOS 27.1, *)
struct RecipeView: View {
var body: some View {
NavigationStack {
ArrangementView {
List {
Text("1. Corta las verduras")
Text("2. Añade el caldo")
Text("3. Cocina durante 20 minutos")
}
} secondary: {
List {
Text("2 zanahorias")
Text("1 puerro")
Text("500 ml de caldo")
}
.splitArrangementLayoutRatio(0.35)
}
.arrangementViewStyle(.split)
.navigationTitle("Crema de verduras")
}
}
}
En una relación de aspecto más ancha que alta, las vistas se distribuyen horizontalmente; en una más alta que ancha, verticalmente. Al plegar parcialmente el iPhone Duo, la división se adapta al pliegue.
ArrangementView organiza contenido, pero no proporciona navegación. Por eso NavigationStack envuelve el contenedor. Apple también recomienda evitar introducir ArrangementView dentro de una List o un ScrollView. En el ejemplo, las listas están dentro de cada región y pueden desplazarse por separado.
Los ejemplos requieren el SDK de iOS 27.1. Si la aplicación admite sistemas anteriores, necesitaremos comprobar la disponibilidad y proporcionar otra composición.
Preferencias de tamaño, no porcentajes inamovibles
splitArrangementLayoutRatio(_:) expresa la proporción preferida para una de las vistas. Aquí solicitamos un 35 % para los ingredientes.
Ese valor se aplica tanto a divisiones horizontales como verticales. Para dar prioridades diferentes según el eje, existe una variante más detallada:
.splitArrangementLayoutRatio(
minHorizontal: 0.3,
idealHorizontal: 0.35,
maxHorizontal: 0.45,
idealVertical: 0.4
)
También tenemos splitArrangementLayoutSize(...) para expresar dimensiones en puntos y splitArrangementFixedLayoutSize(horizontal:vertical:) para preferir el tamaño ideal del contenido.
Conviene entender estos ajustes como preferencias que participan en la distribución. No garantizan una división exacta en todas las situaciones: el espacio necesario para el contenido y la posición del pliegue pueden modificar el resultado.
Limitar los ejes puede ocultar contenido
Podemos permitir únicamente la división horizontal:
.arrangementViewStyle(.split.axes(.horizontal))
Cuando no pueda realizar esa división, el contenedor mostrará solo la vista principal. Para nuestra receta, ocultar los ingredientes impediría cocinar con normalidad, salvo que ofreciéramos otra manera de consultarlos. Limitar un eje exige revisar qué funcionalidades siguen accesibles.
Otra opción consiste en adaptar el contenido al eje actual mediante splitArrangementAxis:
@available(iOS 27.1, *)
struct IngredientsHeading: View {
@Environment(\.splitArrangementAxis) private var axis
var body: some View {
Text(axis == .vertical ? "Necesitas" : "Ingredientes")
.font(.headline)
}
}
El valor es opcional y devuelve nil fuera de una disposición dividida. Podemos usarlo para cambiar la presentación de una subvista sin calcular manualmente la geometría de la pantalla.
Superponer contenido con overlay
Si queremos mostrar un temporizador sobre una fotografía del plato, la relación es diferente. El estilo .overlay coloca la vista principal delante de la secundaria:
ArrangementView {
Text("Tiempo restante: 12:30")
.padding()
.background(.regularMaterial, in: .capsule)
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .bottom
)
.padding()
} secondary: {
Image("vegetable-soup")
.resizable()
.scaledToFit()
}
.arrangementViewStyle(.overlay)
Al plegar parcialmente el dispositivo, las vistas pueden separarse y ocupar regiones distintas. overlayArrangementEdge(_:) permite indicar qué borde debe ocupar una vista cuando se separan.
También podemos consultar overlayArrangementZIndex desde el entorno para adaptar el panel: compacto mientras se superpone y más completo cuando dispone de su propia región. Restringir los ejes de .overlay puede impedir la separación y dejar contenido atravesando el pliegue.
La elección parte de la interfaz: .split encaja cuando necesitamos leer ambas vistas sin que se tapen; .overlay, cuando existe una relación entre fondo y primer plano. Después toca comprobar la pantalla exterior, la interior abierta y las posiciones parcialmente plegadas, incluyendo tamaños de texto grandes.