Básicos
Button
Activa una acción cuando el usuario lo toca. Acepta cualquier vista como label — texto, imagen, o una combinación de ambos. Soporta múltiples estilos visuales con `.buttonStyle()`.
Preview iOS
Código básico
Button("Guardar cambios") {
    guardarCambios()
}

// Con icono
Button {
    eliminar()
} label: {
    Label("Eliminar", systemImage: "trash")
}
.buttonStyle(.borderedProminent)
.tint(.red)
Modificadores comunes
.buttonStyle()
Estilo visual: `.bordered`, `.borderedProminent`, `.plain`
.disabled()
Desactiva la interacción cuando es `true`
.tint()
Color del botón y su resaltado
.controlSize()
Tamaño: `.mini`, `.small`, `.regular`, `.large`
Básicos
Text
Muestra una o más líneas de texto estático. Soporta Markdown inline, interpolación de strings y formateo de fechas/números. Es la vista de display de texto más básica de SwiftUI.
Preview iOS
Título grande
Título 2
Texto cuerpo normal
Texto secundario
Pie de foto / caption
Código básico
Text("Hola, mundo")
    .font(.title)
    .fontWeight(.bold)

// Con Markdown
Text("Texto en **negrita** y *cursiva*")

// Con formato de número
Text(precio, format: .currency(code: "MXN"))
Modificadores comunes
.font()
Fuente: `.title`, `.body`, `.caption`, `.system(size:)`
.fontWeight()
Peso: `.bold`, `.semibold`, `.light`
.foregroundStyle()
Color del texto
.lineLimit()
Número máximo de líneas (nil = ilimitado)
Básicos
Image
Muestra imágenes del catálogo de assets, SF Symbols o URLs remotas (con `AsyncImage`). Por defecto mantiene el aspect ratio original. Se puede escalar y recortar con modificadores.
Preview iOS
👤
★★★★
🏔
Código básico
// SF Symbol
Image(systemName: "star.fill")
    .foregroundStyle(.yellow)

// Asset catalog
Image("avatar")
    .resizable()
    .scaledToFill()
    .frame(width: 80, height: 80)
    .clipShape(Circle())
Modificadores comunes
.resizable()
Permite que la imagen se redimensione
.scaledToFit()
Escala manteniendo el aspect ratio dentro del frame
.scaledToFill()
Rellena el frame, recortando si es necesario
.clipShape()
Recorta la imagen a una forma: `Circle()`, `RoundedRectangle()`
Básicos
Label
Combina un ícono y texto en un layout estándar. Acepta SF Symbols o imágenes del catálogo. Muchos componentes de SwiftUI como `List` y `Menu` aprovechan automáticamente el layout de `Label`.
Preview iOS
❤️Favoritos
📤Compartir
⚙️Ajustes
🗑Eliminar
Código básico
Label("Favoritos", systemImage: "heart.fill")

Label("Compartir", systemImage: "square.and.arrow.up")
    .foregroundStyle(.blue)

// Solo ícono
Label("Ajustes", systemImage: "gear")
    .labelStyle(.iconOnly)
Modificadores comunes
.labelStyle()
`.iconOnly`, `.titleOnly`, `.titleAndIcon` (default)
.foregroundStyle()
Color del ícono y texto
.font()
Tamaño y peso de la fuente
.imageScale()
Escala del ícono: `.small`, `.medium`, `.large`
Input
TextField
Campo de texto editable de una línea. Requiere un `@State` binding para su valor. Muestra el teclado apropiado según el tipo de contenido configurado.
Preview iOS
Abraham
Email
Nombre del proyecto
Código básico
@State private var nombre = ""

TextField("Nombre", text: $nombre)
    .textFieldStyle(.roundedBorder)
    .keyboardType(.default)

// Con label personalizado
TextField(text: $email) {
    Label("Email", systemImage: "envelope")
}
Modificadores comunes
.textFieldStyle()
Estilo visual: `.roundedBorder`, `.plain`
.keyboardType()
Tipo de teclado: `.emailAddress`, `.numberPad`, `.URL`
.autocorrectionDisabled()
Desactiva la autocorrección
.focused()
Controla el foco del campo con un `FocusState`
Input
SecureField
Campo de texto que oculta el contenido con puntos mientras el usuario escribe. Ideal para contraseñas y datos sensibles. Funciona igual que `TextField` pero con entrada enmascarada.
Preview iOS
Contraseña
••••••••
Código básico
@State private var password = ""

SecureField("Contraseña", text: $password)
    .textFieldStyle(.roundedBorder)
    .submitLabel(.done)
    .onSubmit {
        iniciarSesion()
    }
Modificadores comunes
.textFieldStyle()
Estilo visual del campo
.focused()
Controla el foco con un `FocusState`
.submitLabel()
Etiqueta del botón Return: `.done`, `.go`, `.next`
.onSubmit()
Acción al presionar Return
Input
Toggle
Interruptor booleano que alterna entre activo e inactivo. Requiere un binding a un `Bool`. En iOS se renderiza como el switch verde característico del sistema.
Preview iOS
Notificaciones
Modo oscuro
Código básico
@State private var notificaciones = true

Toggle("Notificaciones", isOn: $notificaciones)

// Estilo botón
Toggle("Wi-Fi", isOn: $wifi)
    .toggleStyle(.button)
    .tint(.blue)
Modificadores comunes
.toggleStyle()
Estilo: `.switch` (default), `.button`, `.checkbox`
.tint()
Color cuando está activo (default: verde sistema)
.disabled()
Desactiva la interacción
.labelsHidden()
Oculta el texto label, muestra solo el switch
Input
Slider
Selector de valor continuo dentro de un rango. El usuario arrastra el thumb para seleccionar un valor. Se puede configurar con pasos discretos usando el parámetro `step`.
Preview iOS
🔇
🔊
☀️
☀️
Código básico
@State private var volumen: Double = 0.5

Slider(value: $volumen, in: 0...1)

// Con rango y step
Slider(value: $brillo, in: 0...100, step: 10) {
    Text("Brillo")
} minimumValueLabel: {
    Image(systemName: "sun.min")
} maximumValueLabel: {
    Image(systemName: "sun.max")
}
Modificadores comunes
.tint()
Color del track activo (izquierda del thumb)
.disabled()
Desactiva la interacción
.onChange(of:)
Ejecuta código cada vez que el valor cambia
.accentColor()
Color de acento (alternativa legacy a `.tint()`)
Input
Stepper
Incrementa o decrementa un valor con botones + y −. Acepta un rango y un paso opcional. Útil para cantidades pequeñas donde el usuario necesita control preciso.
Preview iOS
Cantidad: 3
Precio: $150
Código básico
@State private var cantidad = 1

Stepper("Cantidad: \(cantidad)", value: $cantidad, in: 1...10)

// Con paso personalizado
Stepper(value: $precio, in: 0...1000, step: 50) {
    Text("Precio: $\(precio)")
}
Modificadores comunes
.disabled()
Desactiva ambos botones
.onIncrement()
Acción personalizada al incrementar (sin binding)
.onDecrement()
Acción personalizada al decrementar (sin binding)
.font()
Fuente del label
Input
Picker
Selector de una opción entre varias. Soporta múltiples estilos: segmentado, rueda, menú y más. Requiere que las opciones sean `Hashable`. El estilo cambia completamente el look.
Preview iOS
Swift
Kotlin
Dart
Categoría
iOS
Código básico
@State private var seleccion = "Swift"
let opciones = ["Swift", "Kotlin", "Dart"]

Picker("Lenguaje", selection: $seleccion) {
    ForEach(opciones, id: \.self) {
        Text($0)
    }
}
.pickerStyle(.segmented)
Modificadores comunes
.pickerStyle()
`.segmented`, `.wheel`, `.menu`, `.inline`, `.navigationLink`
.tint()
Color de la selección activa
.disabled()
Desactiva la interacción
.labelsHidden()
Oculta el label del picker
Input
DatePicker
Selector de fecha y/u hora. Puede restringirse a mostrar solo fecha, solo hora, o ambas con el parámetro `displayedComponents`. Soporta rango de fechas válidas.
Preview iOS
Fecha de entrega
may 21, 2026
Hora
9:00 AM
Código básico
@State private var fecha = Date()

DatePicker("Fecha de entrega", selection: $fecha,
           in: Date()...,
           displayedComponents: .date)
    .datePickerStyle(.compact)

// Solo hora
DatePicker("Hora", selection: $hora,
           displayedComponents: .hourAndMinute)
Modificadores comunes
.datePickerStyle()
`.compact`, `.graphical`, `.wheel`
.disabled()
Desactiva la selección
in:
Rango de fechas permitidas: `Date()...` para futuras
displayedComponents:
`.date`, `.hourAndMinute`, o ambos
Layout
HStack
Apila sus vistas hijas horizontalmente, de izquierda a derecha. El espaciado entre elementos se controla con `spacing`. La alineación vertical se controla con `alignment`.
Preview iOS
👤
Abraham
iOS Developer
Seguir
Mensaje
Compartir
Código básico
HStack(spacing: 16) {
    Image(systemName: "person.circle")
        .font(.largeTitle)
    VStack(alignment: .leading) {
        Text("Abraham")
            .font(.headline)
        Text("iOS Developer")
            .foregroundStyle(.secondary)
    }
    Spacer()
}
.padding()
Modificadores comunes
alignment:
Alineación vertical: `.top`, `.center`, `.bottom`, `.firstTextBaseline`
spacing:
Espacio en puntos entre elementos (default: 8)
.frame()
Ancho y alto del stack
.padding()
Padding interno alrededor del stack
Layout
VStack
Apila sus vistas hijas verticalmente, de arriba hacia abajo. Es el contenedor más común en SwiftUI. La alineación horizontal se controla con `alignment`.
Preview iOS
Pokédex
151 Pokémon de Kanto
🔴
#001 Bulbasaur
Planta / Veneno
🔥
#004 Charmander
Fuego
Código básico
VStack(alignment: .leading, spacing: 12) {
    Text("Pokédex")
        .font(.largeTitle)
        .fontWeight(.bold)
    Text("151 Pokémon de Kanto")
        .foregroundStyle(.secondary)
    Divider()
    ForEach(pokemones) { p in
        PokemonRow(pokemon: p)
    }
}
.padding()
Modificadores comunes
alignment:
Alineación horizontal: `.leading`, `.center`, `.trailing`
spacing:
Espacio en puntos entre elementos (default: 8)
.frame()
Ancho y alto del stack
.padding()
Padding interno
Layout
ZStack
Superpone sus vistas hijas en el eje Z, de atrás hacia adelante. Cada vista se centra sobre las anteriores por defecto. Ideal para overlays, badges y efectos de capas.
Preview iOS
🎮
3
👤
Código básico
ZStack(alignment: .topTrailing) {
    AsyncImage(url: portadaURL)
        .frame(width: 200, height: 200)
        .clipShape(RoundedRectangle(cornerRadius: 16))

    // Badge encima
    Text("3")
        .font(.caption2).fontWeight(.bold)
        .foregroundStyle(.white)
        .padding(6)
        .background(.red)
        .clipShape(Circle())
        .offset(x: 8, y: -8)
}
Modificadores comunes
alignment:
Punto de anclaje para apilar: `.topLeading`, `.bottomTrailing`, etc.
.zIndex()
Controla el orden Z de un hijo específico
.frame()
Fija el tamaño del ZStack
.clipped()
Recorta el contenido al bounds del ZStack
Layout
Spacer
Ocupa todo el espacio disponible en el eje principal del stack que lo contiene. En un `HStack` se expande horizontalmente, en un `VStack` verticalmente. Empuja el resto de las vistas.
Preview iOS
Título de sección
Editar
☁️iCloud
Activo
Código básico
// Empuja el botón al lado derecho
HStack {
    Text("Título")
        .font(.headline)
    Spacer()
    Button("Editar") { }
}

// Centra el contenido verticalmente
VStack {
    Spacer()
    Text("Centrado")
    Spacer()
}
Modificadores comunes
minLength:
Espacio mínimo garantizado (default: 8)
.frame()
Puede fijar un tamaño máximo
(ningún modificador visible)
Spacer no tiene apariencia visual por sí solo
.hidden()
Oculta pero mantiene el espacio
Layout
Divider
Línea horizontal (en VStack) o vertical (en HStack) que separa visualmente contenido. Adapta su orientación al stack contenedor automáticamente. Fin opaco por defecto.
Preview iOS
Perfil
Notificaciones
Privacidad
Código básico
VStack {
    Text("Sección 1")
    Divider()
    Text("Sección 2")
}

// Personalizado
Divider()
    .overlay(Color.blue.opacity(0.4))
    .padding(.horizontal)
Modificadores comunes
.overlay()
Cambia el color de la línea
.padding()
Agrega espacio alrededor del divider
.frame()
Limita el ancho o alto de la línea
(no tiene modificadores propios)
Usar `.overlay` para personalizar color
Layout
ScrollView
Hace scrolleable su contenido en el eje especificado. Por defecto desplaza verticalmente. Se puede combinar con `LazyVStack` o `LazyHStack` para listas de rendimiento optimizado.
Preview iOS
🎮
Game Progress
Actualizado hoy
📱
MiiboList
hace 2 días
Código básico
ScrollView {
    LazyVStack(spacing: 12) {
        ForEach(items) { item in
            ItemRow(item: item)
        }
    }
    .padding()
}

// Horizontal
ScrollView(.horizontal, showsIndicators: false) {
    HStack { ... }
}
Modificadores comunes
.scrollIndicators()
Muestra u oculta la barra de scroll: `.hidden`, `.visible`
.scrollDisabled()
Desactiva el scroll programáticamente
.scrollTargetBehavior()
Snap entre elementos: `.viewAligned`, `.paging`
.contentMargins()
Márgenes del contenido scrolleable
Contenedores
List
Contenedor de scroll optimizado para mostrar filas de datos. Soporta secciones, swipe actions, pull-to-refresh y selección. Es la forma nativa de iOS de mostrar listas.
Preview iOS
Kanto
🌿
#001 Bulbasaur
Planta
🔥
#004 Charmander
Fuego
Código básico
List(pokemones) { pokemon in
    HStack {
        AsyncImage(url: pokemon.imageURL)
            .frame(width: 44, height: 44)
        VStack(alignment: .leading) {
            Text(pokemon.nombre)
            Text(pokemon.tipo)
                .foregroundStyle(.secondary)
        }
    }
    .swipeActions {
        Button("Favorito", systemImage: "heart") {
            toggleFavorito(pokemon)
        }.tint(.pink)
    }
}
.listStyle(.insetGrouped)
Modificadores comunes
.listStyle()
`.insetGrouped`, `.grouped`, `.plain`, `.sidebar`
.swipeActions()
Acciones de swipe izquierda/derecha por fila
.refreshable()
Agrega pull-to-refresh con async/await
.listRowSeparator()
Muestra u oculta el separador de filas
Contenedores
Form
Contenedor de inputs y controles con el estilo nativo de formularios iOS. Agrupa automáticamente en secciones visuales. Los pickers, toggles y textfields se adaptan al contexto de Form.
Preview iOS
Perfil
NombreAbraham
Emailhi@slekens.dev
Preferencias
Notificaciones
Tema
Oscuro
Código básico
Form {
    Section("Perfil") {
        TextField("Nombre", text: $nombre)
        TextField("Email", text: $email)
    }

    Section("Preferencias") {
        Toggle("Notificaciones", isOn: $notifs)
        Picker("Tema", selection: $tema) {
            Text("Claro").tag("light")
            Text("Oscuro").tag("dark")
        }
    }

    Section {
        Button("Guardar", action: guardar)
            .frame(maxWidth: .infinity)
    }
}
Modificadores comunes
.formStyle()
`.automatic`, `.grouped`, `.columns`
.scrollDisabled()
Desactiva el scroll del form
Section(header:footer:)
Agrupa filas con encabezado y pie opcionales
.disabled()
Desactiva todos los controles del form
Contenedores
Group
Contenedor lógico que agrupa vistas sin afectar el layout. Útil para aplicar un mismo modificador a varios hijos de una vez, o para superar el límite de 10 vistas de un ViewBuilder.
Preview iOS
Metadatos (Group)
Versión: 1.2.0
Build: 42
iOS mínimo: 17.0
Autor: slekens
Código básico
// Aplicar modificador a varios elementos
Group {
    Text("Línea 1")
    Text("Línea 2")
    Text("Línea 3")
}
.font(.caption)
.foregroundStyle(.secondary)

// Superar límite de 10 vistas en ViewBuilder
VStack {
    Group {
        // vistas 1–9
    }
    Group {
        // vistas 10–18
    }
}
Modificadores comunes
.font()
Aplica la fuente a todos los hijos del grupo
.foregroundStyle()
Color aplicado a todos los hijos
.opacity()
Opacidad aplicada a todos los hijos
.disabled()
Desactiva todos los hijos
Contenedores
Section
Agrupa contenido dentro de `List` o `Form` con un encabezado y/o pie opcionales. Se renderiza con estilo nativo según el contexto — inset en `Form`, plano en `List`.
Preview iOS
Mi sección
Elemento 1
Elemento 2
Texto explicativo al pie
Código básico
List {
    Section {
        Text("Elemento 1")
        Text("Elemento 2")
    } header: {
        Text("Mi sección")
    } footer: {
        Text("Texto explicativo al pie")
            .font(.caption)
    }
}
Modificadores comunes
header:
Vista mostrada como encabezado de la sección
footer:
Vista mostrada como pie de la sección
.defaultScrollAnchor()
Ancla de scroll inicial de la sección
(sin modificadores propios)
Section hereda el estilo del contenedor padre
Navegación
NavigationStack
Contenedor principal para navegación por stack (push/pop). Reemplaza a `NavigationView` en iOS 16+. Gestiona automáticamente el historial de navegación y el botón de retroceso.
Preview iOS
Pokédex
🌿Bulbasaur
🔥Charmander
Código básico
NavigationStack {
    List(pokemones) { pokemon in
        NavigationLink(value: pokemon) {
            Text(pokemon.nombre)
        }
    }
    .navigationTitle("Pokédex")
    .navigationDestination(for: Pokemon.self) { pokemon in
        PokemonDetailView(pokemon: pokemon)
    }
    .toolbar {
        ToolbarItem(placement: .topBarTrailing) {
            Button("Filtrar", systemImage: "line.3.horizontal.decrease")
            { mostrarFiltro = true }
        }
    }
}
Modificadores comunes
.navigationTitle()
Título de la barra de navegación (se pone en la vista hija)
.navigationBarTitleDisplayMode()
`.large`, `.inline`, `.automatic`
.toolbar()
Agrega botones a la barra de navegación
.navigationDestination(for:)
Define el destino para un tipo de dato
Navegación
TabView
Muestra múltiples vistas con una barra de tabs en la parte inferior. Cada tab se define con `.tabItem`. Soporta badges numéricos y de texto. Puede usarse también como un pager horizontal.
Preview iOS
Contenido principal
📋Pokédex
❤️Favoritos
3
⚙️Ajustes
Código básico
TabView {
    PokemonListView()
        .tabItem {
            Label("Pokédex", systemImage: "list.bullet")
        }

    FavoritosView()
        .tabItem {
            Label("Favoritos", systemImage: "heart.fill")
        }
        .badge(3)

    AjustesView()
        .tabItem {
            Label("Ajustes", systemImage: "gear")
        }
}
Modificadores comunes
.tabItem()
Define el ícono y texto de cada tab (se aplica al hijo)
.badge()
Badge numérico o de texto sobre el ícono del tab
.tabViewStyle()
`.automatic`, `.page` (pager horizontal)
selection:
Binding para controlar el tab activo programáticamente