Como iOS Developer, una de las decisiones arquitectónicas y de diseño más frecuentes a las que te enfrentarás al construir interfaces es cómo presentar colecciones de datos que exceden el tamaño de la pantalla. En los días de UIKit, la respuesta casi siempre era UITableView o UICollectionView. Hoy, la programación Swift moderna nos ofrece un paradigma declarativo fascinante.
Ambos componentes permiten hacer scroll, ambos pueden mostrar iteraciones de datos, y ambos son compatibles con Xcode para el desarrollo en iOS, macOS y watchOS.
En este extenso tutorial, vamos a desglosar las similitudes, diferencias, ventajas y casos de uso de cada uno, para que domines a la perfección la creación de interfaces con SwiftUI.
1. Entendiendo la base: ¿Qué resuelven List y ScrollView?
Antes de entrar en la comparativa de ScrollView vs List en SwiftUI, es crucial entender la filosofía detrás de cada componente. Ambos existen para resolver el problema del espacio limitado en pantalla, pero lo abordan desde ángulos muy distintos.
La Anatomía de List
List es el equivalente directo de UITableView (en iOS), NSTableView (en macOS) y WKInterfaceTable (en watchOS). Es un componente de alto nivel, fuertemente estandarizado por Apple, que aplica estilos nativos por defecto.
Características principales de List:
- Estilo “Out-of-the-box”: Viene con separadores de celdas, márgenes y comportamientos de agrupación (como
InsetGroupedListStyle) predefinidos por el sistema operativo. - Gestión de interacciones nativas: Soporta acciones como deslizar para eliminar (
.onDelete), reordenar (.onMove) y botones de menú contextual con un esfuerzo mínimo. - Perezosa por defecto: Una
Listno carga todas sus filas en memoria al mismo tiempo. Al igual que el reciclaje de celdas en UIKit, solo renderiza lo que está en pantalla (o a punto de estarlo).
La Anatomía de ScrollView
ScrollView, por otro lado, es un lienzo en blanco. Es el equivalente a un UIScrollView básico. No tiene opiniones sobre cómo deben verse tus datos; simplemente te da un espacio infinito (vertical u horizontal) para colocar vistas y permite al usuario desplazarse por ellas.
Características principales de ScrollView:
- Flexibilidad absoluta: Puedes construir cuadrículas complejas, carruseles horizontales, o vistas de detalle con imágenes de cabecera que se expanden.
- Sin estilos predeterminados: No hay separadores, no hay márgenes predefinidos de lista, ni fondos grises. Lo que diseñas es exactamente lo que obtienes.
- Carga todo en memoria (si usas
VStackoHStack): Por defecto, unScrollViewcombinado con unVStackinstanciará todas las vistas hijas de inmediato. Para lograr el comportamiento “perezoso” de unaList, debes usar explícitamenteLazyVStackoLazyHStack.
2. Similitudes: Donde ambos mundos convergen
A pesar de sus diferencias, cualquier iOS Developer notará rápidamente que la programación Swift los trata de manera similar en la superficie.
- Soporte para
ForEach: Ambos contenedores pueden usarForEachpara iterar sobre colecciones de datos que conformen el protocoloIdentifiable. - Multiplataforma: Tanto
ListcomoScrollViewcompilan de manera transparente en Xcode para iOS, macOS, tvOS y watchOS. - Desplazamiento: Ambos integran el motor físico de Apple para el scroll, incluyendo el rebote (bounce) al llegar a los bordes y el soporte para los indicadores de desplazamiento (scroll indicators).
3. Diferencias Clave: ScrollView vs List en SwiftUI
Aquí es donde la decisión se vuelve crítica para el rendimiento y la Experiencia de Usuario (UX) de tu aplicación.
A. Gestión de Memoria y Rendimiento (Rendimiento Lazy)
El manejo de la memoria es quizás el aspecto técnico más importante al evaluar ScrollView vs List en SwiftUI.
Con List:
La List es inteligente. Si tienes un array de 10,000 elementos, SwiftUI solo creará las vistas para los 10 o 15 elementos que caben en la pantalla. A medida que haces scroll, recicla y renderiza bajo demanda.
import SwiftUI
struct ListExample: View {
let items = Array(1...10000)
var body: some View {
// List es "lazy" por defecto. Carga rápida y eficiente.
List(items, id: \.self) { item in
Text("Fila \(item)")
}
}
}
Con ScrollView:
Si colocas 10,000 elementos en un ScrollView usando un VStack normal, tu aplicación probablemente colapsará o se congelará, porque SwiftUI intentará dibujar las 10,000 vistas antes de mostrar la pantalla. Para igualar el rendimiento de la List, debes usar LazyVStack.
import SwiftUI
struct ScrollViewExample: View {
let items = Array(1...10000)
var body: some View {
ScrollView {
// LazyVStack es obligatorio aquí para colecciones masivas
LazyVStack {
ForEach(items, id: \.self) { item in
Text("Fila \(item)")
// Tienes que añadir tu propio padding y estilo
.padding()
}
}
}
}
}
B. Interactividad y Edición de Datos
Si tu aplicación requiere que el usuario manipule los datos, la balanza se inclina fuertemente hacia la List.
- List: Tiene integración nativa con el entorno de edición (
EditMode). Modificadores como.onDelete(para swipe-to-delete) y.onMove(para arrastrar y soltar) funcionan únicamente dentro de unaListo unForEachrespaldado por unaList. - ScrollView: No soporta
.onDeletede forma nativa. Si quieres implementar la acción de deslizar para eliminar en unScrollView, como iOS Developer tendrás que escribir gestos personalizados (DragGesture) complejos y animaciones manuales para cada fila.
C. Estilos y Separadores
- List: Te da el “Look and Feel” oficial de Apple. Usa
.listStyle(.insetGrouped)en iOS o.listStyle(.sidebar)en macOS para obtener interfaces idénticas a las aplicaciones del sistema. Ocultar los separadores de lista solía ser un dolor de cabeza, aunque desde iOS 15 es más fácil con.listRowSeparator(.hidden). - ScrollView: Te da libertad total. No tienes que pelear contra márgenes indeseados o separadores de sistema. Es ideal para tableros de estilo Pinterest, catálogos de productos o feeds de redes sociales.
4. Comportamiento Multiplataforma: iOS, macOS y watchOS
La belleza de SwiftUI y Xcode es el desarrollo multiplataforma, pero el contexto importa.
En iOS y iPadOS
- List domina las pantallas de configuración (Settings), navegaciones jerárquicas y bandejas de entrada (Mail).
- ScrollView domina los feeds personalizados (Instagram, TikTok), portadas de tiendas (App Store) o cualquier vista donde los elementos tengan tamaños dinámicos e irregulares (usando
LazyVGridoLazyHGrid).
En macOS
En el Mac, el usuario espera soporte completo para el teclado y el ratón.
- Una
Listen macOS maneja automáticamente la selección de filas con el ratón (haciendo clic y arrastrando o usando la teclaShift) y la navegación con las flechas del teclado. - Implementar esta selección múltiple y navegación por teclado en un
ScrollViewrequiere cientos de líneas de programación Swift adicionales.
En watchOS
El Apple Watch tiene una pantalla diminuta y recursos limitados.
- List es casi siempre la opción predeterminada y recomendada por Apple para la navegación en watchOS.
- ScrollView se utiliza principalmente para pantallas de detalle de un solo elemento (por ejemplo, leer un correo electrónico completo o ver un artículo largo).
5. Tabla Comparativa: ScrollView vs List en SwiftUI
Para resumir la batalla técnica, aquí tienes una tabla de referencia rápida para cualquier iOS Developer:
| Característica | List | ScrollView (con LazyVStack) |
|---|---|---|
| Estilo Visual | Nativo (Ajustes, Mail, etc.) | Completamente Personalizado |
| Separadores de Fila | Automáticos (se pueden ocultar) | Ninguno (debes crearlos tú) |
| Dirección de Scroll | Principalmente Vertical | Vertical u Horizontal |
| Gestión de Memoria | Perezosa (Lazy) por defecto | Requiere LazyVStack o LazyHStack |
Swipe to Delete (.onDelete) | Soportado nativamente | No soportado nativamente |
Reordenamiento (.onMove) | Soportado nativamente | No soportado nativamente |
| Soporte de Teclado (macOS) | Excelente (Navegación nativa) | Pobre (Requiere implementación manual) |
| Flexibilidad de Diseño | Rígida (Márgenes forzados) | Absoluta (Control total de píxeles) |
6. Casos de Uso Prácticos y Código
Veamos dos ejemplos claros en Swift de cuándo usar cada uno en tu proyecto de Xcode.
Caso Práctico 1: El Menú de Ajustes (Usa List)
Si estás construyendo la pantalla de configuración de tu aplicación, no reinventes la rueda. Usa List.
import SwiftUI
struct SettingsView: View {
@State private var notificationsEnabled = true
var body: some View {
NavigationStack {
List {
Section(header: Text("Cuenta")) {
Text("Perfil")
Text("Seguridad")
}
Section(header: Text("Preferencias")) {
Toggle("Notificaciones", isOn: $notificationsEnabled)
Text("Apariencia")
}
}
.listStyle(.insetGrouped) // Estilo nativo de iOS
.navigationTitle("Ajustes")
}
}
}
Caso Práctico 2: Feed de Imágenes Tipo Instagram (Usa ScrollView)
Si estás diseñando un feed de contenido visual, historias horizontales o tarjetas personalizadas, una List te limitará demasiado con sus márgenes internos (padding). Aquí brilla el ScrollView.
import SwiftUI
struct SocialFeedView: View {
let imageIDs = Array(1...50)
var body: some View {
NavigationStack {
// Desactivamos los indicadores de scroll para un look más limpio
ScrollView(showsIndicators: false) {
// Usamos LazyVStack por rendimiento
LazyVStack(spacing: 20) {
ForEach(imageIDs, id: \.self) { id in
PostCardView(postID: id)
}
}
.padding(.vertical)
}
.navigationTitle("Mi Feed")
}
}
}
// Vista auxiliar simulada
struct PostCardView: View {
let postID: Int
var body: some View {
VStack(alignment: .leading) {
HStack {
Circle().frame(width: 40, height: 40)
Text("Usuario \(postID)").bold()
Spacer()
}
.padding(.horizontal)
Rectangle()
.fill(Color.gray.opacity(0.3))
.frame(height: 300) // Simula una imagen grande
Text("Descripción fascinante del post número \(postID).")
.padding(.horizontal)
}
}
}
Conclusión
El debate de ScrollView vs List en SwiftUI no se trata de cuál es mejor, sino de cuál es la herramienta adecuada para el trabajo.
Como regla general en la programación Swift:
- Utiliza
Listcuando la estructura y la interacción de los datos (borrar, mover, seleccionar) son más importantes que un diseño visual radicalmente único. Es tu aliado para la productividad y la consistencia nativa. - Utiliza
ScrollView(combinado con Lazy Stacks o Lazy Grids) cuando necesites control absoluto sobre cada píxel de tu diseño, construyendo interfaces ricas y visualmente únicas donde los separadores de sistema o los márgenes predeterminados arruinarían la estética.
Si tienes cualquier duda sobre este artículo, contacta conmigo y estaré encantado de ayudarte . Puedes contactar conmigo en mi perfil de X o en mi perfil de Instagram.








