certmundo.
es‑mx

6 min de lectura

¿Cómo construir una interfaz de usuario básica con SwiftUI?

SwiftUI es el framework de Apple que te permite construir interfaces visuales para iPhone usando estructuras de Swift declarativas y muy poco código.

Con SwiftUI describes qué quieres ver en pantalla, no cómo dibujarlo paso a paso. Eso hace que el código sea más corto y más fácil de leer.

Los bloques básicos de SwiftUI

SwiftUI tiene cuatro vistas que usarás en casi toda app:

Vista ¿Para qué sirve?
Text Mostrar texto estático o dinámico
Button Ejecutar una acción al tocar
TextField Capturar texto del usuario
VStack Apilar vistas una encima de otra

Cada vista es una struct que conforma el protocolo View. Eso conecta directamente con la lección anterior: en SwiftUI, toda pantalla es una struct.

Estructura de una vista SwiftUI

Toda vista SwiftUI sigue este patrón:

struct NombreVista: View {
    var body: some View {
        // tus vistas aquí
    }
}

La propiedad body devuelve exactamente una vista raíz. Si necesitas colocar varias vistas juntas, las envuelves en un contenedor como VStack.

Text — mostrar texto en pantalla

Text es la vista más simple. Recibe un String y lo muestra.

Text("Bienvenido a Liverpool")

Puedes encadenar modificadores para cambiar su apariencia:

Text("Oferta del día")
    .font(.title)
    .foregroundColor(.red)
    .bold()

Cada modificador devuelve una nueva vista. No modifica la vista original: la envuelve. Por eso puedes encadenarlos sin límite.

Button — ejecutar acciones

Un Button tiene dos partes: la acción (qué hace) y la etiqueta (qué muestra).

Button(action: {
    print("Producto agregado al carrito")
}) {
    Text("Agregar al carrito")
}

También existe la sintaxis corta con trailing closure:

Button("Agregar al carrito") {
    print("Producto agregado al carrito")
}

Las dos formas producen el mismo resultado. La segunda es más común en proyectos modernos.

TextField — capturar texto del usuario

TextField necesita dos cosas: un texto de sugerencia (placeholder) y una variable de estado donde guardar lo que escribe el usuario.

Para crear esa variable de estado usas el property wrapper @State:

struct BusquedaView: View {
    @State private var nombreProducto: String = ""

    var body: some View {
        TextField("Busca un producto", text: $nombreProducto)
            .textFieldStyle(.roundedBorder)
            .padding()
    }
}

@State le dice a SwiftUI que esta variable controla la pantalla. Cuando cambia, SwiftUI redibuja body automáticamente.

El símbolo $nombreProducto es un binding: conecta el TextField con la variable para que los cambios fluyan en los dos sentidos.

VStack — organizar vistas verticalmente

VStack apila sus hijos de arriba hacia abajo. Es el contenedor más usado en SwiftUI.

VStack {
    Text("FEMSA — Tienda en línea")
    Text("Selecciona tu producto")
    Button("Ver catálogo") {
        print("Mostrando catálogo")
    }
}

Puedes controlar el espacio entre elementos con el parámetro spacing:

VStack(spacing: 16) {
    Text("Bimbo")
    Text("Pan de caja")
}

Otros contenedores útiles son HStack (horizontal) y ZStack (apilado con capas). En esta lección nos enfocamos en VStack porque cubre la mayoría de los casos básicos.

Ejemplo completo: pantalla de búsqueda de producto

Este ejemplo combina los cuatro elementos en una pantalla funcional al estilo Mercado Libre:

struct BusquedaProductoView: View {
    @State private var busqueda: String = ""
    @State private var resultado: String = "Aquí aparecerá el resultado"

    var body: some View {
        VStack(spacing: 20) {
            Text("Mercado Libre MX")
                .font(.largeTitle)
                .bold()

            TextField("¿Qué estás buscando?", text: $busqueda)
                .textFieldStyle(.roundedBorder)
                .padding(.horizontal)

            Button("Buscar") {
                if busqueda.isEmpty {
                    resultado = "Escribe un producto primero"
                } else {
                    resultado = "Buscando: \(busqueda)"
                }
            }
            .buttonStyle(.borderedProminent)

            Text(resultado)
                .foregroundColor(.secondary)
        }
        .padding()
    }
}

Cuando el usuario escribe "Tenis" y toca "Buscar", el Text inferior muestra:

Buscando: Tenis

Si toca "Buscar" sin escribir nada, muestra:

Escribe un producto primero

Esta lógica condicional dentro del Button es suficiente para muchas pantallas reales.

Ejemplo avanzado: mini formulario de pedido

Este ejemplo simula la captura de un pedido en una app de logística para FEMSA:

struct FormularioPedidoView: View {
    @State private var nombreCliente: String = ""
    @State private var cantidadCajas: String = ""
    @State private var confirmacion: String = ""

    var body: some View {
        VStack(spacing: 18) {
            Text("Nuevo Pedido")
                .font(.title2)
                .bold()

            TextField("Nombre del cliente", text: $nombreCliente)
                .textFieldStyle(.roundedBorder)

            TextField("Número de cajas", text: $cantidadCajas)
                .textFieldStyle(.roundedBorder)
                .keyboardType(.numberPad)

            Button("Registrar pedido") {
                let cajas = Int(cantidadCajas) ?? 0
                let precioPorCaja = 350
                let total = cajas * precioPorCaja
                confirmacion = "Pedido de \(nombreCliente): $\(total)"
            }
            .buttonStyle(.borderedProminent)

            Text(confirmacion)
                .multilineTextAlignment(.center)
                .padding()
        }
        .padding()
    }
}

Si el usuario escribe "Distribuidora del Norte" y "40 cajas", el resultado es:

Pedido de Distribuidora del Norte: $14,000

El modificador .keyboardType(.numberPad) abre el teclado numérico automáticamente en iPhone. Es un detalle pequeño que mejora mucho la experiencia del usuario.

Errores comunes

Error 1 — Olvidar @State en variables que cambian

Si declaras una variable sin @State, SwiftUI no sabe que debe redibujar la pantalla cuando cambie.

// ❌ Incorrecto
var nombre: String = ""

// ✅ Correcto
@State private var nombre: String = ""

El error más común es que escribes en el TextField y la pantalla nunca se actualiza. La causa es casi siempre un @State faltante.

Error 2 — Usar nombreProducto en lugar de $nombreProducto en el TextField

Sin el signo $, pasas el valor actual, no el binding. El TextField no podrá escribir de regreso a tu variable.

// ❌ Incorrecto
TextField("Busca", text: nombreProducto)

// ✅ Correcto
TextField("Busca", text: $nombreProducto)

Xcode te mostrará un error de compilación claro en este caso. Aprende a leerlo: casi siempre dice "cannot convert value of type 'String' to expected argument type 'Binding'".

Error 3 — Poner más de una vista raíz en body sin contenedor

body solo acepta una vista. Si pones dos Text sin envolverlos en VStack, el compilador falla.

// ❌ Incorrecto
var body: some View {
    Text("Línea 1")
    Text("Línea 2")
}

// ✅ Correcto
var body: some View {
    VStack {
        Text("Línea 1")
        Text("Línea 2")
    }
}

Referencia rápida de modificadores útiles

Modificador Efecto
.font(.title) Cambia el tamaño de fuente
.bold() Pone el texto en negritas
.foregroundColor(.red) Cambia el color del texto
.padding() Agrega espacio alrededor
.padding(.horizontal) Espacio solo a los lados
.buttonStyle(.borderedProminent) Botón con fondo de color
.textFieldStyle(.roundedBorder) Campo con borde redondeado
.keyboardType(.numberPad) Abre teclado numérico
.multilineTextAlignment(.center) Centra texto de varias líneas

Puntos clave

  • SwiftUI es declarativo: describes qué mostrar, no cómo dibujarlo.
  • @State marca las variables que controlan la pantalla. Sin él, los cambios no se reflejan visualmente.
  • El binding $variable conecta un TextField con su variable de estado en los dos sentidos.
  • VStack es el contenedor principal para apilar vistas verticalmente. Acepta spacing para controlar la separación.
  • Los modificadores se encadenan después de cualquier vista y transforman su apariencia sin modificar la vista original.

Puntos clave

  • SwiftUI es declarativo: describes qué quieres ver en pantalla y el framework se encarga de dibujarlo. Toda vista es una `struct` que conforma el protocolo `View`.
  • `@State` es el property wrapper que marca las variables que controlan la pantalla. Cuando su valor cambia, SwiftUI redibuja `body` automáticamente.
  • El binding `$variable` conecta un `TextField` con su variable `@State` en ambas direcciones. Sin el signo `$`, el campo no puede actualizar la variable.
  • `VStack` agrupa múltiples vistas en una sola vista raíz y las apila verticalmente. Usa el parámetro `spacing` para controlar el espacio entre elementos.
  • Los modificadores como `.font()`, `.padding()` y `.buttonStyle()` se encadenan después de cualquier vista para cambiar su apariencia sin alterar la vista original.

Comparte esta lección:

¿Cómo construir una interfaz de usuario básica con SwiftUI? | Swift para iOS Básico: Programa tu primera app para iPhone | Certmundo