List — qué es, el componente de lista en SwiftUI

Autor: IT Sectr Publicado: 2026-06-25 Tiempo de lectura: 7 min

List es una View contenedora en SwiftUI para mostrar datos como una lista verticalmente desplazable, análoga a UITableView en UIKit. Según Apple Developer Documentation, 2024, List admite secciones estáticas y dinámicas, acciones de deslizamiento, reordenamiento de filas y pull-to-refresh. A diferencia de UITableView, List utiliza una API declarativa basada en SwiftUI y ForEach, gestionando automáticamente la reutilización de celdas y el rendimiento con una gran cantidad de filas.

Puntos clave

  • List — contenedor para una lista de datos desplazable en SwiftUI
  • ForEach — la forma principal de mostrar datos dinámicamente en List
  • Secciones — Section View para agrupar filas con encabezados
  • Acciones de deslizamiento — swipeActions para iOS 15+
  • Pull-to-refresh — .refreshable para iOS 15+

¿Qué es List en SwiftUI?

List es una View que muestra una secuencia de elementos en una lista verticalmente desplazable. Se introdujo en iOS 13 junto con SwiftUI y es la forma principal de mostrar listas de datos, reemplazando a UITableView de UIKit. List gestiona automáticamente la reutilización de celdas, el desplazamiento y el rendimiento.

List utiliza lazy-loading: las celdas se crean a medida que se desplaza, no todas a la vez. Esto lo diferencia de VStack con ForEach dentro de ScrollView, donde todas las celdas se crean en el momento del renderizado. List también proporciona soporte integrado para acciones de deslizamiento, pull-to-refresh, edición (eliminar/mover) y selección de filas.

Según Apple WWDC 2021 (Session 10072), List en iOS 15+ recibió mejoras significativas de rendimiento gracias a un nuevo mecanismo de diffing a nivel de colecciones. Esto hizo que List fuera más eficiente al actualizar datos, especialmente para listas con cientos de filas.

List vs ScrollView + VStack

Los desarrolladores a menudo eligen entre List y ScrollView con VStack para mostrar un conjunto de Views. La diferencia clave: List utiliza reutilización de celdas (como UITableView), mientras que ScrollView + VStack crea todas las Views inmediatamente. Para listas de tamaño fijo (hasta 20 elementos), la diferencia es insignificante. Para listas dinámicas con 50+ filas, List es preferible por rendimiento.

Listas estáticas y dinámicas

Lista estática es una lista con un número fijo de filas especificadas directamente en el cuerpo de List. Se utiliza para menús, configuraciones y formularios con un conjunto conocido de elementos. Cada fila se declara explícitamente, sin bucles ni ForEach.

swift
// Lista estática (para menús y configuraciones)
List {
    Text("Perfil")
    Text("Configuraciones")
    Text("Acerca de")
}

// Lista dinámica (para datos)
struct UserList: View {
    let users: [User]

    var body: some View {
        List(users) { user in
            HStack {
                Text(user.name)
                Text(user.role)
                    .foregroundColor(.secondary)
            }
        }
    }
}

Lista dinámica utiliza el inicializador List(data:rowContent:) o ForEach dentro del cuerpo de List. El primer enfoque es conveniente cuando cada fila corresponde a un elemento de datos. El segundo es útil cuando hay secciones o elementos adicionales entre los datos.

Identificación (Identifiable): Para listas dinámicas, los elementos de datos deben cumplir con el protocolo Identifiable, o debe especificar un KeyPath a un identificador único en la tupla data:id. SwiftUI utiliza identificadores para rastrear cambios: adiciones, eliminaciones y movimientos de filas.

Secciones y agrupación de datos

Section es una View para agrupar filas en una List con un encabezado y un footer opcional. Section acepta header y footer como ViewBuilder, lo que permite usar no solo texto sino también Views personalizadas para los encabezados de sección.

swift
struct SettingsView: View {
    var body: some View {
        List {
            Section(header: Text("Cuenta")) {
                Text("Nombre")
                Text("Correo electrónico")
            }
            Section(header: Text("Notificaciones")) {
                Toggle("Push", isOn: $pushEnabled)
                Toggle("Email", isOn: $emailEnabled)
            }
        }
        .listStyle(.insetGrouped)
    }
}

// Secciones dinámicas con ForEach
List {
    ForEach(groupedData.keys.sorted(), id: \.self) { key in
        Section(header: Text(key)) {
            ForEach(groupedData[key]!) { item in
                Text(item.title)
            }
        }
    }
}

Estilos de List: SwiftUI proporciona varios estilos integrados a través del modificador .listStyle(). .insetGrouped — estándar para iOS Settings, .plain — minimalista, .inset — con sangría, .sidebar — para Sidebar en iPad.

Según SwiftUI Cookbook (2024), Section con secciones dinámicas y ForEach dentro es un patrón estándar para agrupar datos en aplicaciones con estructura compleja. La regla clave: no anide Section dentro de Section, y no use el inicializador List(data:) junto con Section — use ForEach dentro del cuerpo de List.

Acciones de deslizamiento y pull-to-refresh

.swipeActions(edge:allowsFullSwipe:content:) — un modificador para iOS 15+ que agrega acciones de deslizamiento a las filas de List. Permite mostrar botones al deslizar hacia la izquierda (predeterminado) o hacia la derecha, con diferentes colores y roles (destructive, cancel).

swift
struct TaskList: View {
    @Binding var tasks: [Task]

    var body: some View {
        List {
            ForEach($tasks) { $task in
                Text(task.title)
                    .swipeActions(edge: .trailing) {
                        Button("Eliminar", role: .destructive) {
                            tasks.removeAll { $0.id == task.id }
                        }
                    }
                    .swipeActions(edge: .leading) {
                        Button(task.isDone ? "Deshacer" : "Hecho") {
                            task.isDone.toggle()
                        }
                        .tint(.green)
                    }
            }
        }
        .refreshable {
            // Carga de datos asíncrona
            await loadTasks()
        }
    }
}

.refreshable — un modificador para iOS 15+ que agrega pull-to-refresh. Acepta un closure asíncrono que se ejecuta cuando el usuario tira de la lista hacia abajo. SwiftUI muestra automáticamente un indicador de carga. Una vez que la operación se completa, el indicador se oculta.

.onDelete y .onMove — modificadores para iOS 13+ que agregan soporte para eliminación y reordenamiento de filas. Para usarlos, envuelva los datos en ForEach con Binding o pase closures a través de .onDelete(perform:) en List o ForEach.

Rendimiento de List y optimización

El rendimiento de List depende del número de filas, la complejidad de cada celda y la frecuencia de las actualizaciones de datos. SwiftUI utiliza lazy-loading y reutilización de celdas (similar a UITableView.dequeueReusableCell), pero pueden ser necesarias optimizaciones adicionales para listas con 500+ filas.

OptimizaciónDescripciónVersión iOS
IdentifiableIDs únicos para cada elementoiOS 13+
EquatableViewEvita redibujar cuando los datos son igualesiOS 13+
id(_:)Fuerza la recreación de View cuando cambia el IDiOS 13+
.equatable()Comparación estricta por EquatableiOS 15+
Diffable dataDiff automático en cambiosiOS 15+

Problema 1: Actualizaciones frecuentes. Si los datos en la lista se actualizan con frecuencia (por ejemplo, cada segundo), List puede redibujar las celdas visibles en cada cambio de estado. Solución: use estructuras (value types) para los datos — SwiftUI las compara por valor y redibuja solo las filas cambiadas.

Problema 2: Celdas pesadas. Si cada fila contiene una jerarquía de Views compleja, imágenes y animaciones, el desplazamiento puede ralentizarse. Solución: extraiga las celdas en Views separadas, use EquatableView para evitar redibujados innecesarios. Según SwiftUI Lab (2024), dividir una fila compleja en subcomponentes reduce el tiempo de renderizado en un 30–50%.

Problema 3: Gran número de filas. Con 1000+ filas, List sigue funcionando eficientemente gracias al lazy-loading, pero la carga inicial puede ralentizarse debido al cálculo del layout. Solución: use LazyVStack solo para listas con filas uniformes donde no se necesiten funciones de List (deslizamiento, secciones). Para listas con todas las funciones, List sigue siendo la mejor opción.

Preguntas frecuentes

¿Qué es List en SwiftUI?

List es una View contenedora para mostrar una lista de datos desplazable en SwiftUI. Es el equivalente de UITableView en UIKit con una API declarativa. Admite secciones, acciones de deslizamiento, pull-to-refresh, edición y personalización a través de .listStyle().

¿En qué se diferencia List de ScrollView + VStack?

List utiliza lazy-loading y reutilización de celdas — las celdas se crean a medida que se desplaza. ScrollView + VStack crea todas las Views a la vez. Para listas con 50+ filas, List es preferible. Para conjuntos fijos pequeños (hasta 20 elementos), la diferencia es insignificante.

¿Cómo agregar pull-to-refresh a List?

Use el modificador .refreshable (iOS 15+). Pase un closure asíncrono con la lógica de actualización de datos. SwiftUI muestra automáticamente un indicador de carga y lo oculta después de que la operación asíncrona se completa.

¿Cómo agrupar filas en List?

Use Section View con un encabezado y footer opcional. Coloque las filas de la lista dentro de Section. Para secciones dinámicas, use ForEach con groupedData. El estilo de la lista se configura mediante .listStyle(.insetGrouped) para una apariencia similar a iOS.

¿Cómo acelerar List con un gran número de filas?

Use estructuras (value types) para los datos, extraiga celdas complejas en Views separadas con EquatableView, evite actualizaciones de estado frecuentes en cada fila. Para listas con 1000+ filas, considere LazyVStack si no se necesitan funciones de List.

Resumen

  • List — contenedor para una lista desplazable con lazy-loading y reutilización de celdas
  • ForEach — la forma principal de mostrar datos dinámicamente en List
  • Section — agrupación de filas con encabezados y footer
  • swipeActions — acciones de deslizamiento para iOS 15+
  • refreshable — pull-to-refresh para iOS 15+
  • Estilos — insetGrouped, plain, inset, sidebar mediante .listStyle()
  • Rendimiento — use Identifiable, EquatableView y value types

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.

Discutir el proyecto

Lea también