some View — qué es, tipo opaco en SwiftUI

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

some View es una construcción sintáctica clave de Swift sin la cual SwiftUI no puede funcionar. Según Apple Swift Book, 2024, some View es un tipo opaco (opaque type) que oculta el tipo de retorno específico manteniendo al mismo tiempo una tipificación estricta en tiempo de compilación. Esta construcción permite que el protocolo View tenga una única signatura body sin revelar detalles de implementación.

Puntos clave

  • some View — tipo opaco devuelto por la propiedad body del protocolo View
  • Generics inversos — el tipo concreto lo fija el compilador pero se oculta del código llamante
  • Rendimiento — some View no añade sobrecarga a diferencia de AnyView
  • Limitación — todas las rutas de retorno deben tener el mismo tipo concreto
  • @ViewBuilder resuelve el problema de diferentes tipos mediante ConditionalContent

¿Qué es some View en SwiftUI?

some View es una sintaxis de tipo opaco introducida en Swift 5.1. Se utiliza como tipo de retorno de la propiedad body del protocolo View. La notación some View significa: “la función o propiedad devuelve algún tipo concreto que cumple con el protocolo View, pero el código llamante no sabe ni debe saber cuál”.

El concepto de tipo opaco es la cara inversa de la programación genérica (generics). Si los generics permiten que el código llamante determine el tipo, el tipo opaco permite que la implementación determine el tipo, ocultándolo del llamante. Esto le da al desarrollador la libertad de cambiar la implementación interna sin modificar el contrato.

Según Swift Evolution SE-0244, los tipos opacos se añadieron para soportar SwiftUI y el patrón de protocolos con tipos asociados (PAT), que no se pueden usar como tipo de retorno sin esta construcción.

¿Para qué se necesita some View?

Sin some View, la signatura de body sería imposible: el protocolo View tiene un tipo asociado Body que cumple con View. Si body devolviera simplemente View (como protocolo), Swift no podría trabajar con protocolos con requisitos Self en la posición de retorno. some View resuelve este problema proporcionando un tipo concreto pero oculto.

Tipo opaco: mecanismo de funcionamiento

El tipo opaco es un tipo especial que se comporta como concreto para el compilador pero como abstracto para el desarrollador. Cuando el compilador ve some View, analiza la implementación y determina el tipo de retorno exacto. Este tipo se fija y se utiliza para la generación de código sin despacho dinámico.

swift
struct SimpleView: View {
    var body: some View {
        Text("Hello")
    }
}
// Compiler sees: body -> Text, not some View

Principio de funcionamiento: El compilador de Swift infiere el tipo concreto de la implementación. En el ejemplo anterior, el cuerpo contiene solo Text, por lo que el compilador sabe que body devuelve exactamente Text, aunque la signatura esté escrita como some View. Esto proporciona dos optimizaciones: llamada directa sin tabla de métodos virtuales y posibilidad de inlining.

Si la implementación de body cambia (por ejemplo, en lugar de Text se devuelve un VStack de Text y Button), el compilador redefine el tipo concreto. Pero para el código llamante (SwiftUI), la signatura sigue siendo la misma — some View. Esta es la cara inversa de los generics: el código llamante no depende de los cambios en la implementación.

Fijación del tipo y estabilidad

Una de las reglas clave de los tipos opacos: una función o propiedad que devuelve some View debe devolver siempre el mismo tipo concreto. No se puede devolver Text en una rama if e Image en otra. Esta limitación la verifica el compilador y sirve como garantía para el código llamante.

swift
struct BadView: View {
    var flag: Bool
    var body: some View {
        if flag {
            Text("True")   // Error: Text vs VStack
        } else {
            VStack {
                Text("False")
                Image(systemName: "xmark")
            }
        }
    }
}

Para resolver este problema se utiliza @ViewBuilder, que envuelve diferentes ramas en un contenedor condicional ConditionalContent. La anotación @ViewBuilder sobre body es una práctica estándar en SwiftUI, aunque puede ser implícita si body contiene solo una expresión.

some View vs AnyView: comparación

AnyView es un tipo que borra la implementación concreta de View (type erasure). Envuelve cualquier View en un único envoltorio, permitiendo almacenar Views de diferentes tipos en un mismo contenedor. A diferencia de some View, AnyView funciona en tiempo de ejecución y añade sobrecarga de envoltura y desempaquetado.

Criteriosome ViewAnyView
Momento de resolucióncompilaciónejecución
Rendimientollamada directa, sin sobrecargaenvoltura en existential container
Flexibilidad de tiposun solo tipo concretocualquier tipo View
Cambio dinámicono soportadosoportado en tiempo de ejecución
Prioridad de usosiempre que sea posiblesolo cuando some View es imposible
Soporte de protocolos PAT

Cuándo usar AnyView: solo en situaciones donde some View es imposible debido a la necesidad de cambio dinámico de tipo en tiempo de ejecución. Por ejemplo, al devolver una View desde un diccionario o en una estructura recursiva donde el tipo concreto debe cambiar en cada nivel. AnyView debe minimizarse, ya que cada envoltura desactiva las optimizaciones de SwiftUI.

Concepto erróneo común: AnyView no resuelve el problema de diferentes tipos en body — eso lo resuelve @ViewBuilder. AnyView borra el tipo pero no ayuda al compilador a inferir un tipo único. Use @ViewBuilder para lógica condicional y AnyView solo para despacho dinámico.

some View y @ViewBuilder: trabajo conjunto

@ViewBuilder es un result builder diseñado específicamente para trabajar con some View. Permite usar lógica condicional (if/else, switch) y múltiples expresiones en el cuerpo manteniendo un único tipo de retorno. ViewBuilder envuelve automáticamente múltiples expresiones en TupleView y las ramas condicionales en ConditionalContent.

swift
struct ProfileView: View {
    let user: User?

    @ViewBuilder
    var body: some View {
        if let user {
            UserCard(user: user)
            Text("Online")
                .font(.caption)
        } else {
            ProgressView("Loading...")
        }
    }
}

Cómo funciona: @ViewBuilder analiza el bloque de código y genera la llamada adecuada buildBlock, buildOptional o buildEither. Para la lógica condicional se crea ConditionalContent — un tipo común que oculta los tipos concretos dentro de las ramas pero que en sí mismo es un tipo único para el compilador. Esto resuelve el problema de diferentes tipos concretos.

Sin @ViewBuilder, una propiedad body que contenga múltiples expresiones o lógica condicional provocaría un error de compilación. Es por eso que SwiftUI aplica @ViewBuilder a body implícitamente, y para propiedades y funciones personalizadas debe añadirse explícitamente.

Anidamiento de @ViewBuilder

@ViewBuilder puede anidarse: un ViewBuilder dentro de otro. Esto permite crear jerarquías complejas con condiciones en diferentes niveles. Sin embargo, el anidamiento profundo dificulta la legibilidad, por lo que se recomienda extraer las condiciones anidadas en componentes View separados.

Ejemplos prácticos de some View

Ejemplo 1: devolver una View personalizada desde una propiedad computada. Una propiedad puede devolver some View, ocultando la composición interna. Esto permite reorganizar el código sin cambiar la interfaz pública.

swift
struct ArticleView: View {
    var body: some View {
        CardView {
            HeaderView()
            ContentView()
            FooterView()
        }
    }
}

struct CardView<Content: View>: View {
    let content: Content

    var body: some View {
        content
            .padding(16)
            .background(.white)
            .cornerRadius(12)
            .shadow(radius: 4)
    }
}

Ejemplo 2: pasar una View como clausura mediante @ViewBuilder. Este patrón se usa en los contenedores estándar de SwiftUI (VStack, HStack, List) y puede implementarse en componentes personalizados.

swift
struct CustomContainer<Content: View>: View {
    @ViewBuilder let content: () -> Content

    var body: some View {
        VStack(alignment: .leading) {
            content()
        }
        .padding(20)
    }
}

Ejemplo 3: una función de fábrica que devuelve some View. Permite crear Views según parámetros sin revelar la implementación. Esto es especialmente útil para bibliotecas y componentes reutilizables.

swift
func makeIcon(for status: Status) -> some View {
    switch status {
    case .success:
        Image(systemName: "checkmark.circle.fill")
            .foregroundColor(.green)
    case .error:
        Image(systemName: "xmark.circle.fill")
            .foregroundColor(.red)
    case .pending:
        ProgressView()
    }
}

Preguntas frecuentes

¿Qué significa some View en SwiftUI?

some View es un tipo opaco, lo que significa que se devuelve algún tipo concreto que cumple con el protocolo View. El tipo concreto lo fija el compilador pero se oculta del código llamante. Esto proporciona una tipificación estricta sin revelar detalles de implementación.

¿Cuál es la diferencia entre some View y AnyView?

some View se resuelve en tiempo de compilación con sobrecarga cero. AnyView usa borrado de tipo (type erasure) en tiempo de ejecución con costes adicionales de envoltura en un existential container. Use some View siempre que sea posible, AnyView solo para cambio dinámico de tipo.

¿Por qué no se puede usar some View con diferentes tipos en if/else?

Un tipo opaco requiere un único tipo concreto para todas las rutas de retorno. if/else con diferentes tipos viola este requisito. @ViewBuilder resuelve el problema envolviendo las ramas en ConditionalContent — un tipo único que oculta las diferencias de las implementaciones concretas.

¿Cómo afecta some View al rendimiento de SwiftUI?

some View no reduce el rendimiento — el compilador conoce el tipo exacto y genera código directo. Por el contrario, any View (como protocolo) requeriría despacho dinámico. some View es un mecanismo de optimización integrado en el diseño de SwiftUI.

¿Se puede usar some View fuera de SwiftUI?

Sí, some es una construcción general de Swift 5.1 no vinculada a SwiftUI. Se puede usar con cualquier protocolo: some Equatable, some Codable, some Collection. Es útil para ocultar tipos anidados complejos como [String: [Int]].

Resumen

  • some View — tipo opaco de Swift devuelto por la propiedad body del protocolo View
  • Tipo opaco — la cara inversa de los generics: la implementación determina el tipo, ocultándolo del llamante
  • Compilador fija el tipo concreto en tiempo de compilación para optimizar el código
  • @ViewBuilder resuelve el problema de diferentes tipos mediante ConditionalContent
  • AnyView — borrado de tipo con sobrecarga, úselo solo cuando some View sea imposible
  • Regla de un tipo — todas las rutas de retorno de some View deben tener el mismo tipo concreto
  • some — construcción general de Swift aplicable a cualquier protocolo, no solo a View

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