body: o que é, a propriedade computada View no SwiftUI

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

A propriedade body é o elemento central do protocolo View no SwiftUI, determinando qual conteúdo é exibido na tela. De acordo com Apple Developer Documentation, 2024, body é o único requisito obrigatório do protocolo View e retorna algum tipo que está em conformidade com este mesmo protocolo. O SwiftUI chama body a cada mudança de estado para construir e comparar uma nova árvore de elementos.

Pontos Principais

  • body é uma propriedade computada obrigatória para todos os tipos que implementam o protocolo View
  • some View é um tipo de retorno opaco que permite ao SwiftUI otimizar a renderização
  • body é chamada a cada mudança de estado, mas não deve ter efeitos colaterais
  • ViewBuilder envolve implicitamente body se ela retornar vários elementos
  • body não é chamada se a identidade e o estado da View não mudaram

O que é body no SwiftUI?

body é uma propriedade computada que é o único requisito obrigatório do protocolo View. Toda estrutura em conformidade com View deve implementar body. A propriedade retorna o conteúdo que o SwiftUI exibe na tela — pode ser texto, uma imagem, um botão, um contêiner com elementos aninhados ou qualquer outro tipo em conformidade com o protocolo View.

A assinatura do body é sempre fixa: var body: some View { get }. O tipo de retorno é some View (um tipo opaco), não um tipo concreto. Isso significa que diferentes Views podem retornar diferentes tipos concretos em body, mas o compilador Swift fixa o tipo concreto para cada implementação em tempo de compilação.

De acordo com a WWDC 2022, body é o ponto de entrada para a descrição declarativa da interface. Diferente do UIKit, onde você cria e configura UIView imperativamente, no SwiftUI você descreve declarativamente o que deve ser exibido, e o próprio SwiftUI calcula como implementá-lo.

body como função pura

body deve se comportar como uma função pura — com as mesmas entradas (propriedades da estrutura e estado) deve retornar a mesma árvore View. Se body depender de estado mutável externo (variáveis globais, UserDefaults sem o wrapper @AppStorage), o comportamento se torna imprevisível e o SwiftUI pode redesenhar a tela incorretamente.

Como funciona a propriedade computada body

A propriedade computada body não armazena um valor — ela é calculada cada vez que é acessada. Quando o SwiftUI determina que o estado mudou, ele recria a estrutura View e lê o novo valor de body para obter a árvore de elementos atual para exibição.

swift
struct CounterView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            Text("Contador: \(count)")
                .font(.largeTitle)
            Button("Incrementar") {
                count += 1
            }
            .padding()
            .background(.blue)
            .foregroundColor(.white)
            .cornerRadius(8)
        }
    }
}

Neste exemplo, body retorna um VStack contendo um Text e um botão com modificadores. Quando o botão é pressionado, a propriedade @State count é incrementada, o SwiftUI recria a estrutura CounterView e chama body novamente para obter a árvore atualizada com o novo valor do Text.

Os modificadores (.font, .padding, .background, .foregroundColor, .cornerRadius) não modificam a View original, mas a envolvem em ModifiedContent — um novo tipo que adiciona a modificação. Cada modificador cria outro nível de aninhamento, o que é importante considerar para o desempenho.

body e o tipo opaco some View

some View no tipo de retorno de body não é apenas uma convenção, mas um requisito do compilador. O Swift exige que todos os caminhos de retorno em body tenham o mesmo tipo concreto. Sem @ViewBuilder você não pode retornar Text em um ramo e Button em outro — o compilador produzirá um erro.

swift
struct ConditionalView: View {
    var isReady: Bool

    @ViewBuilder
    var body: some View {
        if isReady {
            Text("Pronto")
                .foregroundColor(.green)
        } else {
            ProgressView()
        }
    }
}

@ViewBuilder em body permite usar lógica condicional (if/else, switch) sem erros de compilação. O ViewBuilder envolve automaticamente diferentes ramos em ConditionalContent — um tipo especial que oculta as diferenças de tipos concretos. Esta é uma capacidade fundamental para construir interfaces dinâmicas.

Sem @ViewBuilder, o compilador tenta inferir um único tipo para todos os caminhos de retorno. Se os tipos diferirem — ocorre um erro. É por isso que o SwiftUI aplica implicitamente @ViewBuilder a body nas declarações View, embora no código do usuário você precise adicionar a anotação explicitamente para métodos e propriedades personalizados que retornam várias Views.

Desempenho de some View

Usar some View em vez de um tipo concreto não reduz o desempenho — o compilador conhece o tipo exato em tempo de compilação e gera código direto sem despacho dinâmico. AnyView, ao contrário, usa apagamento de tipo (type erasure) com a sobrecarga de envolver em um contêiner existencial.

Ciclo de vida do body: quando e como é chamado

body é chamado pelo SwiftUI em três cenários principais: quando a View é exibida pela primeira vez, quando @State/@Binding/@ObservedObject/@StateObject muda, e quando a View pai passa novos valores através do inicializador. O SwiftUI também pode chamar body quando os valores de ambiente (@Environment) mudam.

A frequência das chamadas a body não deve preocupá-lo — o SwiftUI otimiza o redesenho através do mecanismo de identidade. Cada View na hierarquia tem um identificador único. Se a identidade e os dados de entrada não mudaram — body não é chamado mesmo que a View pai seja redesenhada. Isso é alcançado através da comparação Equatable e da estabilidade estrutural.

swift
struct ParentView: View {
    var body: some View {
        ChildView(name: "Alice") // Identidade estável
    }
}

struct ChildView: View {
    let name: String
    var body: some View {
        Text("Olá, \(name)!")
    }
}

Neste exemplo, se ParentView for redesenhada mas passar o mesmo valor de name — ChildView.body não é chamado. O SwiftUI compara os dados de entrada da estrutura e, se não mudaram, ignora o redesenho do componente filho. Este é o mecanismo de diferenciação de views.

Quando body é chamado inesperadamente

Existem várias armadilhas que levam a chamadas inesperadas de body: usar classes sem ObservableObject, passar clousures criadas dentro de body (cada criação de clousure gera uma nova identidade), e o uso incorreto de EquatableView. Se body é chamado com muita frequência — verifique a estabilidade de identidade de todos os componentes filhos.

Melhores práticas para trabalhar com body

Primeira regra: body deve ser mínimo. Mova a lógica complexa para propriedades computadas ou métodos separados que retornam View. Isso melhora a legibilidade e permite que o SwiftUI determine com mais precisão quais partes da hierarquia mudaram. Divida bodies grandes em subcomponentes com limites de responsabilidade claros.

Segunda regra: não use body para realizar trabalho. Carregamento de dados, operações de rede, gravações em banco de dados — tudo isso deve acontecer fora de body, em tarefas (tasks), modificadores onChange ou através de ObservableObject. body é destinado exclusivamente à declaração da interface.

Terceira regra: use a propriedade EquatableView ou um protocolo Equatable personalizado para Views se a comparação estrutural padrão for insuficiente. Isso permite indicar explicitamente ao SwiftUI quando uma View filha precisa ser redesenhada e evitar chamadas desnecessárias a body.

Quarta regra: se body contiver cálculos complexos (formatação, filtragem, ordenação) — use @State para armazenar em cache o resultado ou mova os cálculos para um método separado chamado a partir de onChange. Cálculos repetidos em body a cada atualização de estado são uma causa comum de lentidão de animações.

Quinta regra: para listas (List, ForEach) garanta identificadores estáveis através do parâmetro id. Sem identidade estável, ForEach recria todos os elementos em qualquer alteração, chamando body para cada um deles, mesmo que apenas um elemento tenha mudado.

Perguntas Frequentes

O que é body no SwiftUI?

body é a propriedade computada do protocolo View que retorna o conteúdo para exibição. É o único requisito obrigatório do protocolo. O tipo de retorno é some View, o que permite ao SwiftUI otimizar a hierarquia em tempo de compilação.

Body pode ser chamado várias vezes?

Sim, o SwiftUI chama body a cada mudança de estado (@State, @Binding, @ObservedObject) ou de dados de entrada. Este é um comportamento normal de um framework declarativo. O SwiftUI otimiza a frequência de chamadas através do mecanismo de identidade e da comparação Equatable.

Por que body retorna some View em vez de um tipo concreto?

some View é um tipo opaco que oculta a implementação concreta. O compilador fixa o tipo em tempo de compilação, garantindo o desempenho de chamada direta. Isso oferece flexibilidade: você pode alterar o tipo de retorno sem alterar a assinatura.

Pode-se retornar nil de body?

Não, body não pode ser opcional — o tipo de retorno some View não permite nil. Se precisar ocultar um elemento condicionalmente, use lógica condicional dentro de @ViewBuilder ou retorne EmptyView, que não ocupa espaço na hierarquia.

A quantidade de modificadores afeta o desempenho de body?

Cada modificador cria uma nova camada de ModifiedContent, aumentando a profundidade da hierarquia. Para a maioria das telas (até 50 modificadores) o impacto é insignificante. Uma quantidade excessiva de modificadores (centenas) pode retardar o diffing. Agrupe modificadores relacionados em extensões personalizadas.

Resumo

  • body é a propriedade computada obrigatória do protocolo View que define o conteúdo da tela
  • some View é um tipo de retorno opaco que oculta a implementação concreta do código chamador
  • @ViewBuilder é implicitamente aplicado a body para suportar lógica condicional e múltiplos elementos
  • body não deve conter efeitos colaterais — é uma declaração de interface pura
  • SwiftUI otimiza as chamadas a body através do mecanismo de identidade e comparação Equatable
  • Divida bodies grandes em subcomponentes para melhor desempenho e legibilidade
  • AnyView aumenta a sobrecarga — use @ViewBuilder e Group em vez de apagamento de tipo

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