Section en SwiftUI es un componente contenedor para agrupar lógicamente elementos dentro de Form o List. Muestra el contenido como un bloque visual con espaciado del sistema, esquinas redondeadas y encabezado y pie opcionales. Según la Documentación de Apple Developer (2025), Section no gestiona datos, solo organiza la presentación: todos los elementos secundarios heredan su estilo y espaciado, proporcionando una visualización estructurada de formularios y listas.
Puntos clave
Section es un componente estructural de SwiftUI diseñado para agrupar elementos dentro de contenedores Form y List. A diferencia de VStack o HStack, Section añade espaciado del sistema, un encabezado y pie, así como un resalte visual del grupo en forma de bloque con esquinas redondeadas en iOS.
Section no cambia el comportamiento de los elementos secundarios — solo organiza su presentación. Todos los controles dentro de Section — Picker, Toggle, TextField — funcionan normalmente, pero se combinan visualmente en un grupo lógico. Esto es especialmente importante para formularios en pantalla donde el usuario debe orientarse rápidamente en la estructura de datos.
El sistema gestiona automáticamente los espacios entre secciones: la distancia entre Section en iOS es de 16–20 puntos, entre elementos dentro de Section es 0 (separador entre filas). El desarrollador no puede cambiar estos espacios mediante modificadores de padding — están controlados por el sistema para garantizar una apariencia uniforme.
Section acepta dos parámetros opcionales: header — el título del grupo, y footer — texto explicativo debajo del grupo. El encabezado se muestra sobre los elementos de la sección en negrita con estilo de caption, el pie en fuente más pequeña con color gris. Ambos parámetros aceptan cualquier SwiftUI View, no solo Text.
El encabezado de Section ayuda al usuario a entender a qué categoría pertenecen los elementos del grupo. Por ejemplo, en una pantalla de configuración, encabezados como “Notificaciones”, “Privacidad” y “Cuenta” orientan al usuario al instante. El pie es útil para explicaciones: “Desactive las notificaciones durante reuniones” o “La contraseña debe tener al menos 8 caracteres.” El pie se ajusta automáticamente a varias líneas cuando es necesario.
Section(
header: Text("Account Security"),
footer: Text("Use a strong password with at least 8 characters.")
) {
SecureField("Current password", text: $currentPassword)
SecureField("New password", text: $newPassword)
}
En el ejemplo, Section tiene el encabezado “Account Security” y un pie con consejos de seguridad de contraseña. El usuario ve el encabezado como etiqueta de sección, completa dos campos y lee inmediatamente la advertencia debajo. Esta estructura mejora la UX porque toda la información sobre la sección está en una sola pantalla sin necesidad de ir a una ayuda separada.
Section funciona tanto dentro de Form como de List, pero la representación visual difiere. En Form, Section se muestra como un bloque con esquinas redondeadas y fondo del sistema, separado de secciones adyacentes por espacios. En List, Section puede usar el estilo plain — sin fondo ni esquinas redondeadas, o inset-grouped — con bloques redondeados similares a Form.
La elección del contenedor afecta el estilo de Section. Si colocas una Section con el mismo contenido dentro de Form y List con estilo .insetGrouped, el resultado será idéntico. Sin embargo, Form añade espaciado del sistema y usa estilo grouped por defecto, mientras que List requiere especificación explícita del estilo mediante el modificador .listStyle(.insetGrouped).
| Contenedor | Section por defecto | Estilos disponibles |
|---|---|---|
| Form | InsetGrouped con esquinas redondeadas | .grouped (solo Form) |
| List | Plain — sin fondo de sección | .plain, .inset, .insetGrouped, .sidebar |
Para lograr la misma apariencia en List, usa .listStyle(.insetGrouped). Este estilo imita la apariencia de Form y es adecuado para pantallas de configuración construidas sobre List. Para listas de datos estándar, usa .plain — sin resalte de secciones, con separadores finos entre filas.
Section puede contener una cantidad dinámica de elementos mediante ForEach. Esto permite crear grupos con elementos repetidos manteniendo el encabezado y pie para todo el grupo. ForEach dentro de Section itera sobre una colección de datos y crea Views secundarias para cada elemento sin romper la estructura de la sección.
Las secciones dinámicas son útiles para pantallas de configuración con un número variable de opciones: lista de idiomas disponibles, dispositivos conectados o suscripciones push. El encabezado de la sección permanece estático mientras el contenido cambia según los datos.
struct DynamicSectionView: View {
let categories = ["Work", "Personal", "Finance", "Health"]
@State private var selected = Set<String>()
var body: some View {
Form {
Section(header: Text("Categories"),
footer: Text("Select your preferred categories")) {
ForEach(categories, id: \.self) { category in
Toggle(category, isOn: Binding(
get: { selected.contains(category) },
set: { if $0 { selected.insert(category) }
else { selected.remove(category) } }
))
}
}
Section {
Text("Selected: \(selected.count) categories")
.foregroundStyle(.secondary)
}
}
}
}
En este ejemplo, ForEach genera un Toggle para cada categoría del array categories. El encabezado y pie de la sección se definen una vez y se aplican a todo el grupo. La segunda sección muestra el número de categorías seleccionadas — no depende de ForEach y permanece estática. Este enfoque permite crear formularios flexibles donde el encabezado y pie contextualizan un grupo de elementos dinámicos.
Veamos un ejemplo completo de pantalla de perfil usando Section para agrupar datos. El formulario contiene tres secciones: información del usuario, configuración de privacidad y estadísticas. Cada sección usa su propio encabezado, y la última tiene un pie con información resumida.
struct ProfileView: View {
@State private var displayName = "Alex Johnson"
@State private var bio = "iOS developer"
@State private var isProfilePublic = true
@State private var showEmail = false
var body: some View {
Form {
Section(header: Text("Profile Info")) {
TextField("Display name", text: $displayName)
TextField("Bio", text: $bio, axis: .vertical)
.lineLimit(3)
}
Section(header: Text("Privacy")) {
Toggle("Public profile", isOn: $isProfilePublic)
Toggle("Show email", isOn: $showEmail)
.disabled(!isProfilePublic)
}
Section(header: Text("Stats"),
footer: Text("Last updated today at 2:30 PM")) {
LabeledContent("Posts", value: "42")
LabeledContent("Followers", value: "1,280")
LabeledContent("Following", value: "346")
}
}
.navigationTitle("Profile")
}
}
Tres bloques Section separan claramente las áreas funcionales: campos editables del perfil, interruptores de privacidad y estadísticas. La segunda sección demuestra validación: el interruptor “Show email” está desactivado hasta que el perfil sea público. El pie de la tercera sección muestra la hora de la última actualización — un ejemplo de uso del pie para información contextual adicional. LabeledContent es un componente estándar de SwiftUI para mostrar pares clave-valor en Form.
Section(
header: HStack {
Image(systemName: "bell.fill")
.foregroundStyle(.blue)
Text("Notifications")
.font(.headline)
},
footer: Text("Manage push and email alerts")
) {
Toggle("Push notifications", isOn: $push)
Toggle("Email notifications", isOn: $email)
Stepper("Quiet hours: \(quietStart) — \(quietEnd)",
value: $quietStart,
in: 0...23)
}
Este ejemplo muestra que header puede ser cualquier SwiftUI View. Usar HStack con Image y Text añade un icono junto al encabezado, haciendo la sección visualmente más expresiva. Los encabezados personalizados son útiles para resaltar secciones importantes en la interfaz: configuración de notificaciones, funciones de pago o secciones con advertencias. Sin embargo, no se recomienda abusar de encabezados personalizados — 1–2 secciones con estilo no estándar por pantalla es suficiente para mantener la uniformidad de la interfaz.
Preguntas frecuentes
No, Section no admite anidamiento en SwiftUI. Intentar colocar una Section dentro de otra Section provoca un error de compilación. Para agrupación jerárquica, usa List con OutlineGroup o DisclosureGroup dentro de una Section.
El espacio entre Sections lo gestiona el sistema y no se puede cambiar mediante modificadores de padding. En iOS, la distancia entre secciones es de 16–20 puntos y sigue las HIG. La única forma de afectar el espacio es usar un ListStyle personalizado, pero no se recomienda.
Group es un contenedor invisible para agrupar elementos sin estilo visual. Section añade encabezado, pie, espaciado y un bloque visual. Group se usa para renderizado condicional, Section para estructurar la interfaz.
Sí, Section añade automáticamente etiquetas de accesibilidad. El encabezado de la sección se convierte en un encabezado de accesibilidad del grupo, el pie en una sugerencia de accesibilidad. VoiceOver lee el encabezado antes de entrar en la sección, mejorando la navegación para usuarios con discapacidades.
No, Section solo funciona dentro de Form o List. Usar Section fuera de estos contenedores provoca un error de compilación. Para agrupar elementos en VStack o ScrollView, usa Group o Views personalizadas con configuración manual de espaciado.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también