body: qué es, la propiedad computada View en SwiftUI

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

La propiedad body es el elemento central del protocolo View en SwiftUI, que determina qué contenido se muestra en la pantalla. Según Apple Developer Documentation, 2024, body es el único requisito obligatorio del protocolo View y devuelve un tipo que se ajusta a este mismo protocolo. SwiftUI llama a body con cada cambio de estado para construir y comparar un nuevo árbol de elementos.

Puntos Clave

  • body es una propiedad computada obligatoria para todos los tipos que implementan el protocolo View
  • some View es un tipo opaco de retorno que permite a SwiftUI optimizar el renderizado
  • body se llama con cada cambio de estado pero no debe tener efectos secundarios
  • ViewBuilder envuelve implícitamente body si devuelve múltiples elementos
  • body no se llama si la identidad y el estado de View no han cambiado

¿Qué es body en SwiftUI?

body es una propiedad computada que es el único requisito obligatorio del protocolo View. Cada estructura que se ajuste a View debe implementar body. La propiedad devuelve el contenido que SwiftUI muestra en la pantalla — puede ser texto, una imagen, un botón, un contenedor con elementos anidados o cualquier otro tipo que se ajuste al protocolo View.

La firma de body siempre es fija: var body: some View { get }. El tipo de retorno es some View (un tipo opaco), no un tipo concreto. Esto significa que diferentes Views pueden devolver diferentes tipos concretos en body, pero el compilador de Swift fija el tipo concreto para cada implementación en tiempo de compilación.

Según WWDC 2022, body es el punto de entrada para la descripción declarativa de la interfaz. A diferencia de UIKit, donde creas y configuras UIView de forma imperativa, en SwiftUI describes declarativamente lo que debe mostrarse, y SwiftUI mismo calcula cómo implementarlo.

body como función pura

body debe comportarse como una función pura — con las mismas entradas (propiedades de la estructura y estado) debe devolver el mismo árbol View. Si body depende de un estado mutable externo (variables globales, UserDefaults sin el envoltorio @AppStorage), el comportamiento se vuelve impredecible y SwiftUI podría redibujar la pantalla incorrectamente.

Cómo funciona la propiedad computada body

La propiedad computada body no almacena un valor — se calcula cada vez que se accede a ella. Cuando SwiftUI determina que el estado ha cambiado, recrea la estructura View y lee el nuevo valor de body para obtener el árbol de elementos actualizado para su visualización.

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)
        }
    }
}

En este ejemplo, body devuelve un VStack que contiene un Text y un botón con modificadores. Cuando se presiona el botón, la propiedad @State count se incrementa, SwiftUI recrea la estructura CounterView y vuelve a llamar a body para obtener el árbol actualizado con el nuevo valor de Text.

Los modificadores (.font, .padding, .background, .foregroundColor, .cornerRadius) no modifican la View original sino que la envuelven en ModifiedContent — un nuevo tipo que añade la modificación. Cada modificador crea otro nivel de anidamiento, lo cual es importante considerar para el rendimiento.

body y el tipo opaco some View

some View en el tipo de retorno de body no es solo una convención sino un requisito del compilador. Swift requiere que todas las rutas de retorno en body tengan el mismo tipo concreto. Sin @ViewBuilder no puedes devolver Text en una rama y Button en otra — el compilador producirá un error.

swift
struct ConditionalView: View {
    var isReady: Bool

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

@ViewBuilder en body permite usar lógica condicional (if/else, switch) sin errores de compilación. ViewBuilder envuelve automáticamente las diferentes ramas en ConditionalContent — un tipo especial que oculta las diferencias de tipos concretos. Esta es una capacidad clave para construir interfaces dinámicas.

Sin @ViewBuilder el compilador intenta inferir un único tipo para todas las rutas de retorno. Si los tipos difieren — se produce un error. Es por esto que SwiftUI aplica implícitamente @ViewBuilder a body en las declaraciones View, aunque en el código de usuario hay que añadir la anotación explícitamente para métodos y propiedades personalizados que devuelvan múltiples Views.

Rendimiento de some View

Usar some View en lugar de un tipo concreto no reduce el rendimiento — el compilador conoce el tipo exacto en tiempo de compilación y genera código directo sin despacho dinámico. AnyView, por el contrario, usa borrado de tipo (type erasure) con la sobrecarga de envolver en un contenedor existencial.

Ciclo de vida de body: cuándo y cómo se llama

body es llamado por SwiftUI en tres escenarios principales: cuando la View se muestra por primera vez, cuando cambia @State/@Binding/@ObservedObject/@StateObject, y cuando la View padre pasa nuevos valores a través del inicializador. SwiftUI también puede llamar a body cuando cambian los valores de entorno (@Environment).

La frecuencia de las llamadas a body no debería preocuparte — SwiftUI optimiza el redibujado mediante el mecanismo de identidad. Cada View en la jerarquía tiene un identificador único. Si la identidad y los datos de entrada no han cambiado — body no se llama aunque la View padre se redibuje. Esto se logra mediante la comparación Equatable y la estabilidad estructural.

swift
struct ParentView: View {
    var body: some View {
        ChildView(name: "Alice") // Identidad estable
    }
}

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

En este ejemplo, si ParentView se redibuja pero pasa el mismo valor de name — ChildView.body no se llama. SwiftUI compara los datos de entrada de la estructura y, si no han cambiado, omite el redibujado del componente hijo. Este es el mecanismo de diferenciación de vistas.

Cuando body se llama inesperadamente

Existen varios problemas que provocan llamadas inesperadas a body: usar clases sin ObservableObject, pasar closures creadas dentro de body (cada creación de closure genera una nueva identidad), y el uso incorrecto de EquatableView. Si body se llama con demasiada frecuencia — verifica la estabilidad de identidad de todos los componentes hijos.

Mejores prácticas para trabajar con body

Primera regla: body debe ser mínimo. Traslada la lógica compleja a propiedades computadas o métodos separados que devuelvan View. Esto mejora la legibilidad y permite a SwiftUI determinar con mayor precisión qué partes de la jerarquía han cambiado. Divide bodies grandes en subcomponentes con límites de responsabilidad claros.

Segunda regla: no uses body para realizar trabajo. Carga de datos, operaciones de red, escrituras en base de datos — todo esto debe ocurrir fuera de body, en tasks, modificadores onChange o a través de ObservableObject. body está destinado únicamente a la declaración de la interfaz.

Tercera regla: usa la propiedad EquatableView o un protocolo Equatable personalizado para Views si la comparación estructural estándar es insuficiente. Esto permite indicar explícitamente a SwiftUI cuándo una View hija necesita un redibujado y evitar llamadas innecesarias a body.

Cuarta regla: si body contiene cálculos complejos (formateo, filtrado, ordenación) — usa @State para almacenar en caché el resultado o traslada los cálculos a un método separado llamado desde onChange. Los cálculos repetidos en body con cada actualización de estado son una causa común de ralentización de animaciones.

Quinta regla: para listas (List, ForEach) asegura identificadores estables mediante el parámetro id. Sin identidad estable, ForEach recrea todos los elementos ante cualquier cambio, llamando a body para cada uno de ellos, incluso si solo cambió un elemento.

Preguntas Frecuentes

¿Qué es body en SwiftUI?

body es la propiedad computada del protocolo View que devuelve el contenido para mostrar. Es el único requisito obligatorio del protocolo. El tipo de retorno es some View, lo que permite a SwiftUI optimizar la jerarquía en tiempo de compilación.

¿Puede body llamarse varias veces?

Sí, SwiftUI llama a body con cada cambio de estado (@State, @Binding, @ObservedObject) o de datos de entrada. Este es un comportamiento normal de un framework declarativo. SwiftUI optimiza la frecuencia de llamadas mediante el mecanismo de identidad y la comparación Equatable.

¿Por qué body devuelve some View en lugar de un tipo concreto?

some View es un tipo opaco que oculta la implementación concreta. El compilador fija el tipo en tiempo de compilación, asegurando el rendimiento de llamada directa. Esto proporciona flexibilidad: puedes cambiar el tipo de retorno sin cambiar la firma.

¿Se puede devolver nil desde body?

No, body no puede ser opcional — el tipo de retorno some View no permite nil. Si necesitas ocultar un elemento condicionalmente, usa lógica condicional dentro de @ViewBuilder o devuelve EmptyView, que no ocupa espacio en la jerarquía.

¿Afecta la cantidad de modificadores al rendimiento de body?

Cada modificador crea una nueva capa de ModifiedContent, aumentando la profundidad de la jerarquía. Para la mayoría de las pantallas (hasta 50 modificadores) el impacto es insignificante. Una cantidad excesiva de modificadores (cientos) puede ralentizar el diffing. Agrupa modificadores relacionados en extensiones personalizadas.

Resumen

  • body es la propiedad computada obligatoria del protocolo View que define el contenido de la pantalla
  • some View es un tipo opaco de retorno que oculta la implementación concreta del código llamante
  • @ViewBuilder se aplica implícitamente a body para soportar lógica condicional y múltiples elementos
  • body no debe contener efectos secundarios — es una declaración de interfaz pura
  • SwiftUI optimiza las llamadas a body mediante el mecanismo de identidad y la comparación Equatable
  • Divide los bodies grandes en subcomponentes para un mejor rendimiento y legibilidad
  • AnyView aumenta la sobrecarga — usa @ViewBuilder y Group en lugar del borrado de tipo

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