some View — qu’est-ce que c’est, type opaque dans SwiftUI

Auteur : IT Sectr Publié le : 2026-06-24 Temps de lecture : 8 min

some View est une construction syntaxique clé de Swift sans laquelle SwiftUI ne peut pas fonctionner. Selon Apple Swift Book, 2024, some View est un type opaque qui cache le type de retour spécifique tout en maintenant un typage strict au moment de la compilation. Cette construction permet au protocole View d’avoir une signature body unifiée sans révéler les détails d’implémentation.

Points clés

  • some View — type opaque retourné par la propriété body du protocole View
  • Generics inversés — le type concret est fixé par le compilateur mais caché au code appelant
  • Performances — some View n’ajoute pas de surcharge contrairement à AnyView
  • Limitation — tous les chemins de retour doivent avoir le même type concret
  • @ViewBuilder résout le problème des différents types via ConditionalContent

Qu’est-ce que some View dans SwiftUI ?

some View est une syntaxe de type opaque introduite dans Swift 5.1. Elle est utilisée comme type de retour de la propriété body du protocole View. La notation some View signifie : « la fonction ou propriété retourne un type concret qui se conforme au protocole View, mais le code appelant ne sait pas et ne doit pas savoir lequel ».

Le concept de type opaque est le revers de la programmation générique (generics). Si les generics permettent au code appelant de déterminer le type, le type opaque permet à l’implémentation de déterminer le type, en le cachant à l’appelant. Cela donne au développeur la liberté de modifier l’implémentation interne sans changer le contrat.

Selon Swift Evolution SE-0244, les types opaques ont été ajoutés pour supporter SwiftUI et le motif des protocoles avec types associés (PAT), qui ne peuvent pas être utilisés comme type de retour sans cette construction.

Pourquoi some View est nécessaire

Sans some View, la signature body serait impossible : le protocole View a un type associé Body qui se conforme à View. Si body retournait simplement View (comme protocole), Swift ne pourrait pas travailler avec des protocoles ayant des exigences Self en position de retour. some View résout ce problème en fournissant un type concret mais caché.

Type opaque : mécanisme de fonctionnement

Le type opaque est un type spécial qui se comporte comme concret pour le compilateur mais comme abstrait pour le développeur. Lorsque le compilateur voit some View, il analyse l’implémentation et détermine le type de retour exact. Ce type est fixé et utilisé pour la génération de code sans dispatch dynamique.

swift
struct SimpleView: View {
    var body: some View {
        Text("Bonjour")
    }
}
// Le compilateur voit : body -> Text, not some View

Principe de fonctionnement : Le compilateur Swift déduit le type concret de l’implémentation. Dans l’exemple ci-dessus, le corps contient uniquement Text, donc le compilateur sait que body retourne exactement Text, même si la signature est écrite comme some View. Cela offre deux optimisations : appel direct sans table de méthodes virtuelles et possibilité d’inlining.

Si l’implémentation de body change (par exemple, au lieu de Text, un VStack de Text et Button est retourné), le compilateur redéfinit le type concret. Mais pour le code appelant (SwiftUI), la signature reste la même — some View. C’est le revers des generics : le code appelant ne dépend pas des changements d’implémentation.

Fixation du type et stabilité

Une des règles clés des types opaques : une fonction ou propriété retournant some View doit toujours retourner le même type concret. On ne peut pas retourner Text dans une branche if et Image dans une autre. Cette limitation est vérifiée par le compilateur et sert de garantie pour le code appelant.

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

Pour résoudre ce problème, on utilise @ViewBuilder, qui enveloppe différentes branches dans un conteneur conditionnel ConditionalContent. L’annotation @ViewBuilder sur body est une pratique standard dans SwiftUI, bien qu’elle puisse être implicite si body ne contient qu’une seule expression.

some View vs AnyView : comparaison

AnyView est un type qui efface l’implémentation concrète de View (type erasure). Il enveloppe n’importe quel View dans un unique emballage, permettant de stocker des Views de différents types dans le même conteneur. Contrairement à some View, AnyView fonctionne à l’exécution et ajoute une surcharge d’empaquetage et de dépaquetage.

Critèresome ViewAnyView
Temps de résolutioncompilationexécution
Performancesappel direct, sans surchargeempaquetage dans un existential container
Flexibilité des typesun seul type concrettout type View
Changement dynamiquenon supportésupporté à l’exécution
Priorité d’utilisationtoujours quand possibleseulement quand some View est impossible
Support des protocoles PATouioui

Quand utiliser AnyView : uniquement dans les situations où some View est impossible en raison de la nécessité d’un changement dynamique de type à l’exécution. Par exemple, lors du retour d’un View depuis un dictionnaire ou dans une structure récursive où le type concret doit changer à chaque niveau. AnyView doit être minimisé, car chaque empaquetage désactive les optimisations de SwiftUI.

Idée reçue courante : AnyView ne résout pas le problème des différents types dans body — c’est @ViewBuilder qui le résout. AnyView efface le type mais n’aide pas le compilateur à déduire un type unique. Utilisez @ViewBuilder pour la logique conditionnelle et AnyView uniquement pour le dispatch dynamique.

some View et @ViewBuilder : travail conjoint

@ViewBuilder est un result builder conçu spécifiquement pour travailler avec some View. Il permet d’utiliser une logique conditionnelle (if/else, switch) et des expressions multiples dans le body tout en maintenant un type de retour unique. ViewBuilder enveloppe automatiquement les expressions multiples dans TupleView et les branches conditionnelles dans ConditionalContent.

swift
struct ProfileView: View {
    let user: User?

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

Comment ça fonctionne : @ViewBuilder analyse le bloc de code et génère l’appel approprié buildBlock, buildOptional ou buildEither. Pour la logique conditionnelle, ConditionalContent est créé — un type commun qui cache les types concrets à l’intérieur des branches mais est lui-même un type unique pour le compilateur. Cela résout le problème des différents types concrets.

Sans @ViewBuilder, une propriété body contenant des expressions multiples ou une logique conditionnelle provoquerait une erreur de compilation. C’est pourquoi SwiftUI applique @ViewBuilder à body implicitement, et pour les propriétés et fonctions personnalisées, il doit être ajouté explicitement.

Imbrication de @ViewBuilder

@ViewBuilder peut être imbriqué : un ViewBuilder à l’intérieur d’un autre. Cela permet de créer des hiérarchies complexes avec des conditions à différents niveaux. Cependant, une imbrication profonde complique la lisibilité, il est donc recommandé d’extraire les conditions imbriquées dans des composants View séparés.

Exemples pratiques de some View

Exemple 1 : retourner un View personnalisé depuis une propriété calculée. Une propriété peut retourner some View, cachant la composition interne. Cela permet de réorganiser le code sans modifier l’interface publique.

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

Exemple 2 : passer un View comme closure via @ViewBuilder. Ce motif est utilisé dans les conteneurs standard de SwiftUI (VStack, HStack, List) et peut être implémenté dans des composants personnalisés.

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

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

Exemple 3 : une fonction d’usine qui retourne some View. Permet de créer des Views en fonction de paramètres sans révéler l’implémentation. C’est particulièrement utile pour les bibliothèques et les composants réutilisables.

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

Foire aux questions

Que signifie some View dans SwiftUI ?

some View est un type opaque, ce qui signifie qu’un type concret conforme au protocole View est retourné. Le type concret est fixé par le compilateur mais caché au code appelant. Cela assure un typage strict sans révéler les détails d’implémentation.

Quelle est la différence entre some View et AnyView ?

some View est résolu à la compilation avec une surcharge nulle. AnyView utilise le type erasure à l’exécution avec des coûts supplémentaires d’empaquetage dans un existential container. Utilisez some View autant que possible, AnyView uniquement pour le changement dynamique de type.

Pourquoi some View ne peut-il pas être utilisé avec différents types dans if/else ?

Un type opaque nécessite un type concret unique pour tous les chemins de retour. if/else avec différents types viole cette exigence. @ViewBuilder résout le problème en enveloppant les branches dans ConditionalContent — un type unique qui cache les différences des implémentations concrètes.

Comment some View affecte-t-il les performances de SwiftUI ?

some View ne réduit pas les performances — le compilateur connaît le type exact et génère du code direct. En revanche, any View (comme protocole) nécessiterait un dispatch dynamique. some View est un mécanisme d’optimisation intégré dans la conception de SwiftUI.

Peut-on utiliser some View en dehors de SwiftUI ?

Oui, some est une construction générale de Swift 5.1 non liée à SwiftUI. Elle peut être utilisée avec n’importe quel protocole : some Equatable, some Codable, some Collection. C’est utile pour cacher des types imbriqués complexes comme [String: [Int]].

Résumé

  • some View — type opaque Swift retourné par la propriété body du protocole View
  • Type opaque — le revers des generics : l’implémentation détermine le type, le cachant à l’appelant
  • Compilateur fixe le type concret à la compilation pour l’optimisation du code
  • @ViewBuilder résout le problème des différents types via ConditionalContent
  • AnyView — type erasure avec surcharge, à utiliser seulement quand some View est impossible
  • Règle d’un type — tous les chemins de retour de some View doivent avoir le même type concret
  • some — construction générale de Swift applicable à tout protocole, pas seulement View

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi