Form en SwiftUI es un componente contenedor para construir interfaces estructuradas de configuración y entrada de datos, siguiendo el diseño de Settings en iOS. El componente agrupa automáticamente los controles en secciones con espaciado y estilos del sistema, liberando al desarrollador del ajuste manual de separadores y colores. Según la Documentación de Apple Developer (2025), Form adapta su apariencia a cada plataforma — desde tablas agrupadas en iOS hasta listas estándar en macOS — manteniendo una API unificada.
Puntos clave
Form es un contenedor especializado de SwiftUI diseñado para crear formularios de entrada y pantallas de configuración. Hereda el comportamiento de List pero añade estilos específicos de la plataforma: en iOS, Form se muestra como una tabla agrupada con esquinas redondeadas; en macOS, aparece como una lista estándar del sistema con casillas de verificación y controles.
A diferencia del diseño manual con VStack y HStack, Form organiza automáticamente el espaciado entre elementos, añade separadores y adapta su apariencia al tema del sistema — claro u oscuro. El desarrollador solo describe la estructura lógica: Section para agrupar y los controles dentro. El propio formulario decide cómo disponer visualmente Picker, Toggle o Stepper en cada plataforma.
Form admite todos los elementos de entrada estándar de SwiftUI: TextField para texto, SecureField para contraseñas, Picker para selección de lista, Toggle para encendido/apagado, Slider para rangos, Stepper para valores incrementales y DatePicker para fechas. Cada elemento obtiene automáticamente un estilo acorde con las HIG (Human Interface Guidelines) de Apple en la plataforma objetivo.
A pesar de su similitud visual, Form y List resuelven tareas diferentes. List es un contenedor universal para mostrar listas desplazables de datos con acciones de deslizamiento y edición de filas. Form es un contenedor especializado para entrada de datos y configuración, optimizado para estilos de control del sistema.
List es adecuado para mostrar datos dinámicos: feeds de noticias, chats, catálogos de productos. Form es para pantallas estáticas con un conjunto predecible de campos: perfil de usuario, configuración de la aplicación, formulario de registro. La diferencia clave: los elementos de Form pueden ser controles interactivos, mientras que las filas de List generalmente muestran datos y responden al toque con navegación o acción.
| Parámetro | Form | List |
|---|---|---|
| Propósito | Entrada de datos, configuración | Visualización de listas |
| Estilo de secciones | Grouped (iOS), sistema (macOS) | Plain o Grouped |
| Controles | Picker, Toggle, Slider, Stepper | Limitados (botón) |
| Datos dinámicos | Limitado (ForEach dentro de Section) | Soporte completo |
| Acciones de deslizamiento | Sí, swipeActions | Sí, swipeActions |
Según las Apple Human Interface Guidelines (2025), Form debe usarse para pantallas de configuración y entrada donde haya de 3 a 20 controles en una pantalla y dividirlos en secciones mejora la usabilidad.
Section es el bloque de construcción principal de Form, que permite agrupar elementos lógicamente relacionados. Cada Section puede tener un encabezado, un pie de página y cualquier número de controles en su interior. El sistema añade automáticamente espaciado entre secciones y envuelve cada una en un bloque visual con esquinas redondeadas.
Usar Section es fundamental para la legibilidad del formulario: los elementos agrupados por significado son más fáciles de procesar para el usuario. Por ejemplo, en una pantalla de configuración de perfil, se pueden separar «Datos personales», «Notificaciones» y «Seguridad» en secciones individuales. Cada sección puede contener un pie de página con texto explicativo que el sistema muestra en una fuente más pequeña debajo del grupo de elementos.
Form {
Section(header: Text("Perfil")) {
TextField("Nombre", text: $name)
TextField("Email", text: $email)
}
Section(header: Text("Notificaciones"),
footer: Text("Desactivar durante reuniones")) {
Toggle("Push notifications", isOn: $pushEnabled)
Toggle("Email notifications", isOn: $emailEnabled)
}
}
En el ejemplo, la primera sección «Profile» contiene dos campos de texto sin pie de página, la segunda sección «Notifications» contiene dos interruptores con una explicación debajo del grupo. El pie de página añade automáticamente espaciado y usa el estilo de fuente caption. Una Section puede tener un pie de página sin encabezado o un encabezado sin pie de página.
Form admite todos los elementos de entrada estándar de SwiftUI. Picker en Form se muestra automáticamente como una fila de navegación con transición a una pantalla de selección separada en iOS. Toggle aparece como una fila con un interruptor alineado a la derecha. TextField obtiene el estilo de entrada del sistema con un marcador de posición.
Para valores numéricos se usan Stepper (cambio incremental) y Slider (cambio suave en un rango). DatePicker admite varios modos: date, time, dateAndTime. ColorPicker está disponible para selección de color. Cada elemento se adapta a la plataforma sin código adicional — en iOS los controles usan estilos nativos de UIKit, en macOS usan AppKit.
| Elemento | Propósito | Estilo en Form |
|---|---|---|
| TextField | Entrada de texto | Fila con marcador de posición |
| SecureField | Entrada de contraseña | Fila con caracteres ocultos |
| Picker | Selección de lista | NavigationLink a pantalla de selección |
| Toggle | Encendido/Apagado | Fila con interruptor |
| Slider | Rango de valores | Deslizador horizontal |
| DatePicker | Selección de fecha/hora | Estilo compacto o de rueda |
Para controles personalizados dentro de Form se puede usar cualquier SwiftUI View — heredan el comportamiento estándar de la sección. Sin embargo, se recomienda usar elementos del sistema, ya que garantizan el cumplimiento de HIG y admiten Accesibilidad (VoiceOver, Dynamic Type) sin configuración adicional.
Creemos una pantalla de registro usando Form. El formulario contiene cuatro secciones: datos personales, selección de rol, configuración de suscripción y un botón de envío. Se usa Section para agrupar y controles estándar de SwiftUI.
struct RegistrationForm: View {
@State private var name = ""
@State private var email = ""
@State private var role = "Developer"
@State private var agreedToTerms = false
let roles = ["Developer", "Designer", "Manager"]
var body: some View {
NavigationStack {
Form {
Section(header: Text("Información personal")) {
TextField("Name", text: $name)
TextField("Email", text: $email)
.keyboardType(.emailAddress)
}
Section(header: Text("Rol")) {
Picker("Select role", selection: $role) {
ForEach(roles, id: \.self) { role in
Text(role).tag(role)
}
}
}
Section {
Toggle("Agree to terms", isOn: $agreedToTerms)
}
Section {
Button("Registrarse") {
submitForm()
}
.disabled(!agreedToTerms)
}
}
.navigationTitle("Registration")
}
}
private func submitForm() { }
}
El formulario está dividido en cuatro Section: datos personales con dos campos de texto, selección de rol mediante Picker, aceptación de términos mediante Toggle y un botón de registro. El botón está deshabilitado hasta que el usuario acepte los términos — esto es un ejemplo de validación dentro de Form. NavigationStack añade un título y permite que Picker abra una pantalla de selección separada en iOS.
struct SettingsForm: View {
@State private var volume: Double = 0.5
@State private var isDarkMode = false
@State private var reminderDate = Date()
var body: some View {
NavigationStack {
Form {
Section(header: Text("Apariencia")) {
Toggle("Dark mode", isOn: $isDarkMode)
Slider(value: $volume, in: 0...1) {
Text("Volumen")
}
}
Section(header: Text("Recordatorios"),
footer: Text("Recibirás una notificación a la hora seleccionada")) {
DatePicker("Remind at",
selection: $reminderDate,
displayedComponents: .hourAndMinute)
}
Section {
NavigationLink("Advanced Settings",
destination: AdvancedSettingsView())
}
}
.navigationTitle("Settings")
}
}
}
Este ejemplo demuestra una combinación de Slider, DatePicker y NavigationLink dentro de Form. DatePicker usa el modo hourAndMinute para mostrar solo la hora. NavigationLink en la última sección crea una transición a una pantalla de configuración avanzada — un patrón común para interfaces tipo Settings. Los encabezados y pies de página de las secciones hacen que el formulario sea autodocumentado: el usuario entiende inmediatamente a qué grupo pertenece cada control.
Preguntas frecuentes
Form está optimizado para entrada de datos y configuración: los controles obtienen estilos del sistema, las secciones obtienen esquinas redondeadas y espaciado. List es un contenedor universal para visualización de datos. Form es adecuado para pantallas de configuración, List es para chats, feeds, catálogos.
Sí, Picker dentro de Form se muestra automáticamente como una fila con el valor seleccionado y un NavigationLink para selección de lista en iOS. En macOS, Picker aparece como una lista desplegable o grupo de radio según el estilo. La adaptación ocurre sin código adicional.
Cualquier SwiftUI View puede colocarse dentro de Form o Section. Para controles personalizados, se recomienda heredar el espaciado estándar de la sección y admitir Dynamic Type mediante fuentes del sistema. Evite tamaños y colores fijos para que el formulario se muestre correctamente en todos los dispositivos.
Sí, Form se envuelve automáticamente en un ScrollView si el contenido supera la altura de la pantalla. No es necesario agregar ScrollView manualmente — el sistema mismo determina si se necesita desplazamiento. Para formularios que no deben desplazarse, use VStack con una altura fija.
Form en iOS admite dos estilos mediante el modificador .formStyle(.grouped) — la vista agrupada estándar con secciones redondeadas. En macOS está disponible .formStyle(.columns) con diseño de varias columnas. El estilo se aplica a todo el Form a la vez y cambia la representación visual de todos los elementos internos.
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