@ViewBuilder: qué es, result builder para View en SwiftUI

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

@ViewBuilder es una anotación result builder en SwiftUI diseñada para la construcción declarativa de jerarquías de View. Según Apple Developer Documentation, 2024, @ViewBuilder transforma un bloque de código con múltiples expresiones y lógica condicional en un único tipo View comprensible para el compilador de Swift. Sin esta anotación, sería imposible usar la sintaxis declarativa familiar de SwiftUI con if/else y múltiples elementos en el body.

Puntos clave

  • @ViewBuilder — result builder que compone múltiples Views en una composición sin contenedores adicionales
  • buildBlock — envuelve una secuencia de expresiones en TupleView de hasta 10 elementos
  • buildEither — crea ConditionalContent para ramas if/else y switch
  • Limitación — hasta 10 elementos en un solo bloque sin Group o ForEach
  • Aplicación implícita — body ya está envuelto en @ViewBuilder, las funciones personalizadas requieren anotación explícita

¿Qué es @ViewBuilder en SwiftUI?

@ViewBuilder es una anotación que implementa el patrón result builder (SE-0289), que permite a SwiftUI componer múltiples Views en una sola composición mediante sintaxis declarativa. Automáticamente envuelve múltiples expresiones, construcciones condicionales y valores opcionales en sus tipos correspondientes: TupleView, ConditionalContent, OptionalContent.

Antes de los result builders, los desarrolladores tenían que envolver manualmente los elementos en VStack o HStack, y usar operadores ternarios o métodos de fábrica para la lógica condicional. @ViewBuilder hizo que la sintaxis de SwiftUI fuera concisa y legible, permitiendo escribir código que parece Swift normal con if/else y bucles.

Según Swift Evolution SE-0289, los result builders son un mecanismo general no vinculado a SwiftUI. @ViewBuilder es una implementación de este mecanismo, junto con @StringBuilder para la construcción de cadenas y las implementaciones de bibliotecas para otros DSL. En SwiftUI, @ViewBuilder se usa no solo para body, sino también para los parámetros de cierre de contenedores (VStack, HStack, ZStack, List).

Diferencia con el enfoque imperativo

En UIKit imperativo, creas explícitamente un UIView, configuras sus propiedades y lo agregas a la jerarquía mediante addSubview. En SwiftUI con @ViewBuilder, describes declarativamente qué Views deben mostrarse, y SwiftUI maneja la creación, actualización y eliminación de elementos según los cambios de estado.

Cómo funciona @ViewBuilder: result builder

Result builder es un mecanismo de Swift que transforma una secuencia de expresiones en un único valor compuesto mediante los métodos estáticos buildBlock, buildOptional, buildEither y otros. Cuando el compilador ve la anotación @ViewBuilder, aplica automáticamente estos métodos al bloque de código durante la compilación.

swift
@resultBuilder
struct ViewBuilder {
    static func buildBlock<C0, C1>(_ c0: C0, _ c1: C1) -> TupleView<(C0, C1)>
    static func buildIf<C>(_ c: C?) -> C?
    static func buildEither<T, F>(first: T) -> ConditionalContent<T, F>
    static func buildEither<T, F>(second: F) -> ConditionalContent<T, F>
}

buildBlock acepta de 1 a 10 expresiones y devuelve un TupleView. Cada aridad (número de expresiones) tiene su propia sobrecarga de buildBlock: desde buildBlock hasta buildBlock. Por eso el número de elementos en un solo bloque @ViewBuilder está limitado a 10.

buildEither (first/second) maneja las construcciones if/else. Cada rama se pasa al método correspondiente, y el resultado se envuelve en ConditionalContent, un tipo que oculta los tipos específicos de las ramas y proporciona una interfaz unificada para SwiftUI.

Comportamiento implícito de @ViewBuilder

En SwiftUI, la propiedad body ya está anotada implícitamente con @ViewBuilder — no ves esta anotación en el código, pero el compilador la aplica automáticamente. Sin embargo, para propiedades personalizadas que devuelven múltiples Views, o para parámetros de cierre, la anotación debe especificarse explícitamente.

Limitaciones de @ViewBuilder y cómo evitarlas

Limitación 1 — 10 elementos en un bloque. Esta es la limitación más conocida de @ViewBuilder. Si necesitas mostrar más de 10 elementos en el mismo nivel, el compilador emitirá un error. Las soluciones incluyen Group, ForEach, List o dividir en subcomponentes. Group no agrega anidamiento visual, pero cada Group cuenta como un elemento.

swift
struct ManyElementsView: View {
    var body: some View {
        Group {
            Text("1"); Text("2"); Text("3")
            Text("4"); Text("5"); Text("6")
            Text("7"); Text("8"); Text("9")
        }
        Group {
            Text("10"); Text("11"); Text("12")
        }
    }
}

Limitación 2 — falta de soporte para ciertas construcciones. @ViewBuilder no admite do/catch, guard, for-in (sin ForEach) y otras construcciones de control de flujo. Para bucles, usa ForEach con datos identificables. Para el manejo de errores, usa Views separadas que acepten Result o valores opcionales.

Limitación 3 — complejidad de depuración. Cuando ocurren errores en @ViewBuilder, el compilador produce mensajes extensos donde es difícil encontrar la causa raíz. Problemas típicos: falta de coincidencia de tipos en ramas if/else, exceder el límite de 10 elementos o falta de sobrecargas necesarias de buildBlock.

Patrones de uso de @ViewBuilder

Patrón 1: visualización condicional mediante if/else. El caso de uso más común de @ViewBuilder. Permite mostrar diferentes Views según el estado sin usar operadores ternarios o métodos de fábrica.

swift
struct StatusView: View {
    var status: LoadStatus

    @ViewBuilder
    var body: some View {
        switch status {
        case .loading:
            ProgressView("Loading...")
        case .loaded(let data):
            DataView(data: data)
        case .error(let message):
            ErrorView(message: message)
        }
    }
}

Patrón 2: @ViewBuilder en parámetros de funciones e inicializadores. Se usa para crear contenedores reutilizables que aceptan Views hijas mediante un cierre. Este es el patrón estándar para bibliotecas y componentes de UI.

swift
struct SectionCard<Content: View>: View {
    let title: String
    @ViewBuilder let content: Content

    var body: some View {
        VStack(alignment: .leading) {
            Text(title).font(.headline)
            content
        }
        .padding()
        .background(Color.gray.opacity(0.1))
        .cornerRadius(12)
    }
}

Patrón 3: composición con ForEach. @ViewBuilder funciona correctamente con ForEach, permitiendo la generación dinámica de elementos a partir de un array de datos. Cada elemento de ForEach cuenta como una expresión en el contexto de @ViewBuilder.

Creación de un ViewBuilder personalizado para componentes reutilizables

ViewBuilder personalizado es una función o propiedad definida por el usuario anotada con @ViewBuilder que devuelve some View. Estas funciones permiten encapsular lógica de visualización compleja y reutilizarla en diferentes partes de la aplicación.

swift
struct FormRow<Content: View>: View {
    let label: String
    @ViewBuilder let content: Content

    var body: some View {
        HStack {
            Text(label)
                .frame(width: 120, alignment: .trailing)
            content
        }
    }
}

// Uso:
FormRow(label: "Name") {
    TextField("Enter name", text: $name)
}

FormRow(label: "Gender") {
    Picker("Select", selection: $gender) {
        Text("Hombre").tag(Gender.male)
        Text("Mujer").tag(Gender.female)
    }
}

Regla importante: una función personalizada con @ViewBuilder debe devolver some View, no un tipo concreto ni el protocolo View. Solo un tipo opaco permite ocultar la implementación concreta preservando la flexibilidad de composición.

Rendimiento: las funciones personalizadas @ViewBuilder no añaden sobrecarga en comparación con el código directo en body. El compilador inlinea las llamadas y optimiza el código resultante. Dividir body en funciones @ViewBuilder mejora la legibilidad sin sacrificar el rendimiento.

Preguntas frecuentes

¿Qué es @ViewBuilder en SwiftUI?

@ViewBuilder es una anotación result builder que transforma un bloque de código con múltiples expresiones y condiciones en un único tipo View. Permite usar la sintaxis familiar de Swift (if/else, switch, expresiones opcionales) dentro de la UI declarativa de SwiftUI.

¿Por qué no se pueden poner más de 10 elementos en @ViewBuilder?

La limitación proviene de la implementación de buildBlock — existe una sobrecarga separada del método para cada aridad de 1 a 10. Swift no admite genéricos variádicos, por lo que el número de sobrecargas es fijo. Para evitarlo, usa Group, ForEach o subcomponentes.

¿Necesito especificar explícitamente @ViewBuilder antes de body?

No, el protocolo View aplica implícitamente @ViewBuilder a la propiedad body. Sin embargo, para propiedades personalizadas, métodos y parámetros de cierre que devuelvan múltiples Views, la anotación debe especificarse explícitamente. Sin ella, el compilador no podrá manejar múltiples expresiones.

¿Cómo maneja @ViewBuilder las expresiones opcionales?

Para expresiones opcionales, se usa el método buildIf, que acepta un View opcional y lo devuelve si existe un valor. Si el valor es nil, buildIf devuelve nil y el elemento no se muestra. Esto permite usar if let dentro del body.

¿Se puede usar @ViewBuilder con switch?

Sí, desde Swift 5.9 @ViewBuilder admite switch a través del método buildExpression. El compilador transforma cada rama case en la correspondiente llamada buildEither. El soporte de switch hace que el código sea más legible en comparación con las construcciones if/else anidadas.

Resumen

  • @ViewBuilder — result builder para la construcción declarativa de jerarquías View en SwiftUI
  • buildBlock envuelve una secuencia de expresiones en TupleView (hasta 10 elementos)
  • buildEither crea ConditionalContent para ramas if/else y switch
  • buildIf maneja expresiones opcionales y if sin else
  • Group y ForEach ayudan a evitar el límite de 10 elementos por bloque
  • Funciones @ViewBuilder personalizadas mejoran la reutilización sin pérdida de rendimiento
  • @ViewBuilder se aplica implícitamente a body, pero requiere anotación explícita para parámetros

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