@ViewBuilder: o que é, result builder para View no SwiftUI

Autor: IT Sectr Publicado: 2026-06-24 Tempo de leitura: 7 min

@ViewBuilder é uma anotação result builder no SwiftUI projetada para a construção declarativa de hierarquias de View. De acordo com Apple Developer Documentation, 2024, o @ViewBuilder transforma um bloco de código com múltiplas expressões e lógica condicional em um único tipo View compreensível para o compilador Swift. Sem esta anotação, seria impossível usar a sintaxe declarativa familiar do SwiftUI com if/else e múltiplos elementos no body.

Principais conclusões

  • @ViewBuilder — result builder que compõe múltiplas Views em uma composição sem contêineres extras
  • buildBlock — envolve uma sequência de expressões em TupleView de até 10 elementos
  • buildEither — cria ConditionalContent para ramos if/else e switch
  • Limitação — até 10 elementos em um único bloco sem Group ou ForEach
  • Aplicação implícita — body já está envolto em @ViewBuilder, funções personalizadas exigem anotação explícita

O que é @ViewBuilder no SwiftUI?

@ViewBuilder é uma anotação que implementa o padrão result builder (SE-0289), que permite ao SwiftUI compor múltiplas Views em uma única composição usando sintaxe declarativa. Ela automaticamente envolve múltiplas expressões, construções condicionais e valores opcionais em seus tipos correspondentes: TupleView, ConditionalContent, OptionalContent.

Antes dos result builders, os desenvolvedores tinham que envolver manualmente os elementos em VStack ou HStack, e usar operadores ternários ou métodos de fábrica para lógica condicional. O @ViewBuilder tornou a sintaxe do SwiftUI concisa e legível, permitindo escrever código que se parece com Swift normal com if/else e loops.

De acordo com Swift Evolution SE-0289, result builders são um mecanismo geral não vinculado ao SwiftUI. O @ViewBuilder é uma implementação deste mecanismo, junto com o @StringBuilder para construção de strings e implementações de bibliotecas para outros DSLs. No SwiftUI, @ViewBuilder é usado não apenas para body, mas também para parâmetros de closure de contêineres (VStack, HStack, ZStack, List).

Diferença da abordagem imperativa

No UIKit imperativo, você cria explicitamente um UIView, configura suas propriedades e o adiciona à hierarquia via addSubview. No SwiftUI com @ViewBuilder, você descreve declarativamente quais Views devem ser exibidas, e o SwiftUI gerencia a criação, atualização e remoção de elementos com base nas mudanças de estado.

Como @ViewBuilder funciona: result builder

Result builder é um mecanismo do Swift que transforma uma sequência de expressões em um único valor composto através dos métodos estáticos buildBlock, buildOptional, buildEither e outros. Quando o compilador vê a anotação @ViewBuilder, ele aplica automaticamente esses métodos ao bloco de código durante a compilação.

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 aceita de 1 a 10 expressões e retorna um TupleView. Cada aridade (número de expressões) tem sua própria sobrecarga de buildBlock: de buildBlock a buildBlock. É por isso que o número de elementos em um único bloco @ViewBuilder é limitado a 10.

buildEither (first/second) lida com construções if/else. Cada ramo é passado para o método correspondente, e o resultado é envolto em ConditionalContent — um tipo que oculta os tipos específicos dos ramos e fornece uma interface unificada para o SwiftUI.

Comportamento implícito do @ViewBuilder

No SwiftUI, a propriedade body já está implicitamente anotada com @ViewBuilder — você não vê essa anotação no código, mas o compilador a aplica automaticamente. No entanto, para propriedades personalizadas que retornam múltiplas Views, ou para parâmetros de closure, a anotação deve ser especificada explicitamente.

Limitações do @ViewBuilder e como contorná-las

Limitação 1 — 10 elementos em um bloco. Esta é a limitação mais conhecida do @ViewBuilder. Se você precisar exibir mais de 10 elementos no mesmo nível, o compilador emitirá um erro. As soluções incluem Group, ForEach, List ou divisão em subcomponentes. Group não adiciona aninhamento visual, mas cada Group conta como um 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")
        }
    }
}

Limitação 2 — falta de suporte para certas construções. O @ViewBuilder não suporta do/catch, guard, for-in (sem ForEach) e outras construções de fluxo de controle. Para loops, use ForEach com dados identificáveis. Para tratamento de erros, use Views separadas que aceitam Result ou valores opcionais.

Limitação 3 — complexidade de depuração. Quando ocorrem erros no @ViewBuilder, o compilador produz mensagens extensas onde é difícil encontrar a causa raiz. Problemas típicos: incompatibilidade de tipos em ramos if/else, exceder o limite de 10 elementos ou falta de sobrecargas necessárias de buildBlock.

Padrões de uso do @ViewBuilder

Padrão 1: exibição condicional via if/else. O caso de uso mais comum do @ViewBuilder. Permite mostrar diferentes Views com base no estado sem usar operadores ternários ou 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)
        }
    }
}

Padrão 2: @ViewBuilder em parâmetros de funções e inicializadores. Usado para criar contêineres reutilizáveis que aceitam Views filhas através de um closure. Este é o padrão padrão para bibliotecas e 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)
    }
}

Padrão 3: composição com ForEach. O @ViewBuilder funciona corretamente com ForEach, permitindo a geração dinâmica de elementos a partir de um array de dados. Cada elemento do ForEach conta como uma expressão no contexto do @ViewBuilder.

Criação de um ViewBuilder personalizado para componentes reutilizáveis

ViewBuilder personalizado é uma função ou propriedade definida pelo usuário anotada com @ViewBuilder que retorna some View. Essas funções permitem encapsular lógica de exibição complexa e reutilizá-la em diferentes partes da aplicação.

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("Masculino").tag(Gender.male)
        Text("Feminino").tag(Gender.female)
    }
}

Regra importante: uma função personalizada com @ViewBuilder deve retornar some View, não um tipo concreto ou o protocolo View. Apenas um tipo opaco permite ocultar a implementação concreta preservando a flexibilidade de composição.

Desempenho: funções personalizadas @ViewBuilder não adicionam sobrecarga em comparação com o código direto no body. O compilador inlinea as chamadas e otimiza o código resultante. Dividir body em funções @ViewBuilder melhora a legibilidade sem sacrificar o desempenho.

Perguntas frequentes

O que é @ViewBuilder no SwiftUI?

@ViewBuilder é uma anotação result builder que transforma um bloco de código com múltiplas expressões e condições em um único tipo View. Permite usar a sintaxe familiar do Swift (if/else, switch, expressões opcionais) dentro da UI declarativa do SwiftUI.

Por que não é possível colocar mais de 10 elementos no @ViewBuilder?

A limitação vem da implementação do buildBlock — existe uma sobrecarga separada do método para cada aridade de 1 a 10. O Swift não suporta genéricos variádicos, então o número de sobrecargas é fixo. Para contornar, use Group, ForEach ou subcomponentes.

Preciso especificar explicitamente @ViewBuilder antes do body?

Não, o protocolo View aplica implicitamente @ViewBuilder à propriedade body. No entanto, para propriedades personalizadas, métodos e parâmetros de closure que retornam múltiplas Views, a anotação deve ser especificada explicitamente. Sem ela, o compilador não conseguirá lidar com múltiplas expressões.

Como o @ViewBuilder lida com expressões opcionais?

Para expressões opcionais, o método buildIf é usado, que aceita um View opcional e o retorna se existir um valor. Se o valor for nil, buildIf retorna nil e o elemento não é exibido. Isso permite usar if let dentro do body.

Pode-se usar @ViewBuilder com switch?

Sim, desde o Swift 5.9 o @ViewBuilder suporta switch através do método buildExpression. O compilador transforma cada ramo case na chamada buildEither correspondente. O suporte a switch torna o código mais legível em comparação com construções if/else aninhadas.

Resumo

  • @ViewBuilder — result builder para construção declarativa de hierarquias View no SwiftUI
  • buildBlock envolve uma sequência de expressões em TupleView (até 10 elementos)
  • buildEither cria ConditionalContent para ramos if/else e switch
  • buildIf lida com expressões opcionais e if sem else
  • Group e ForEach ajudam a contornar o limite de 10 elementos por bloco
  • Funções @ViewBuilder personalizadas melhoram a reutilização sem perda de desempenho
  • @ViewBuilder é aplicado implicitamente ao body, mas requer anotação explícita para parâmetros

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também