body : qu'est-ce que c'est, la propriété calculée View dans SwiftUI

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

La propriété body est l'élément central du protocole View dans SwiftUI, déterminant quel contenu est affiché à l'écran. Selon Apple Developer Documentation, 2024, body est la seule exigence obligatoire du protocole View et retourne un type qui est conforme à ce même protocole. SwiftUI appelle body à chaque changement d'état pour construire et comparer une nouvelle arborescence d'éléments.

Points Clés

  • body est une propriété calculée obligatoire pour tous les types qui implémentent le protocole View
  • some View est un type de retour opaque qui permet à SwiftUI d'optimiser le rendu
  • body est appelée à chaque changement d'état mais ne doit pas avoir d'effets secondaires
  • ViewBuilder enveloppe implicitement body si elle retourne plusieurs éléments
  • body n'est pas appelée si l'identité et l'état de la View n'ont pas changé

Qu'est-ce que body dans SwiftUI ?

body est une propriété calculée qui est la seule exigence obligatoire du protocole View. Toute structure conforme à View doit implémenter body. La propriété retourne le contenu que SwiftUI affiche à l'écran — cela peut être du texte, une image, un bouton, un conteneur avec des éléments imbriqués ou tout autre type conforme au protocole View.

La signature de body est toujours fixe : var body: some View { get }. Le type de retour est some View (un type opaque), pas un type concret. Cela signifie que différentes Views peuvent retourner différents types concrets dans body, mais le compilateur Swift fixe le type concret pour chaque implémentation au moment de la compilation.

Selon la WWDC 2022, body est le point d'entrée pour la description déclarative de l'interface. Contrairement à UIKit, où vous créez et configurez UIView de manière impérative, dans SwiftUI vous décrivez de manière déclarative ce qui doit être affiché, et SwiftUI lui-même calcule comment l'implémenter.

body comme fonction pure

body doit se comporter comme une fonction pure — avec les mêmes entrées (propriétés de la structure et état) elle doit retourner la même arborescence View. Si body dépend d'un état mutable externe (variables globales, UserDefaults sans le wrapper @AppStorage), le comportement devient imprévisible et SwiftUI peut redessiner l'écran de manière incorrecte.

Comment fonctionne la propriété calculée body

La propriété calculée body ne stocke pas de valeur — elle est calculée à chaque accès. Lorsque SwiftUI détermine que l'état a changé, il recrée la structure View et lit la nouvelle valeur de body pour obtenir l'arborescence d'éléments actuelle à afficher.

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

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

Dans cet exemple, body retourne un VStack contenant un Text et un bouton avec des modificateurs. Lorsque le bouton est pressé, la propriété @State count est incrémentée, SwiftUI recrée la structure CounterView et appelle à nouveau body pour obtenir l'arborescence mise à jour avec la nouvelle valeur du Text.

Les modificateurs (.font, .padding, .background, .foregroundColor, .cornerRadius) ne modifient pas la View originale mais l'enveloppent dans ModifiedContent — un nouveau type qui ajoute la modification. Chaque modificateur crée un autre niveau d'imbrication, ce qui est important à considérer pour les performances.

body et le type opaque some View

some View dans le type de retour de body n'est pas seulement une convention mais une exigence du compilateur. Swift exige que tous les chemins de retour dans body aient le même type concret. Sans @ViewBuilder, vous ne pouvez pas retourner Text dans une branche et Button dans une autre — le compilateur produira une erreur.

swift
struct ConditionalView: View {
    var isReady: Bool

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

@ViewBuilder sur body permet d'utiliser une logique conditionnelle (if/else, switch) sans erreurs de compilation. ViewBuilder enveloppe automatiquement les différentes branches dans ConditionalContent — un type spécial qui cache les différences de types concrets. C'est une capacité clé pour construire des interfaces dynamiques.

Sans @ViewBuilder, le compilateur tente d'inférer un seul type pour tous les chemins de retour. Si les types diffèrent — une erreur se produit. C'est pourquoi SwiftUI applique implicitement @ViewBuilder à body dans les déclarations View, bien que dans le code utilisateur, vous deviez ajouter explicitement l'annotation pour les méthodes et propriétés personnalisées qui retournent plusieurs Views.

Performances de some View

Utiliser some View au lieu d'un type concret ne réduit pas les performances — le compilateur connaît le type exact au moment de la compilation et génère du code direct sans dispatch dynamique. AnyView, au contraire, utilise l'effacement de type (type erasure) avec la surcharge d'encapsulation dans un conteneur existentiel.

Cycle de vie de body : quand et comment elle est appelée

body est appelée par SwiftUI dans trois scénarios principaux : lors du premier affichage de la View, lors du changement de @State/@Binding/@ObservedObject/@StateObject, et lorsque la View parent transmet de nouvelles valeurs via l'initialiseur. SwiftUI peut également appeler body lors du changement de valeurs d'environnement (@Environment).

La fréquence des appels à body ne devrait pas vous inquiéter — SwiftUI optimise le redessin grâce au mécanisme d'identité. Chaque View dans la hiérarchie a un identifiant unique. Si l'identité et les données d'entrée n'ont pas changé — body n'est pas appelée même si la View parent est redessinée. Ceci est réalisé par la comparaison Equatable et la stabilité structurelle.

swift
struct ParentView: View {
    var body: some View {
        ChildView(name: "Alice") // Identité stable
    }
}

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

Dans cet exemple, si ParentView est redessinée mais transmet la même valeur name — ChildView.body n'est pas appelée. SwiftUI compare les données d'entrée de la structure et, si inchangées, ignore le redessin du composant enfant. C'est le mécanisme de différenciation de vues.

Quand body est appelée de manière inattendue

Plusieurs pièges entraînent des appels inattendus de body : l'utilisation de classes sans ObservableObject, le passage de fermetures créées à l'intérieur de body (chaque création de fermeture donne une nouvelle identité), et l'utilisation incorrecte d'EquatableView. Si body est appelée trop souvent — vérifiez la stabilité d'identité de tous les composants enfants.

Meilleures pratiques pour travailler avec body

Première règle : body doit être minimal. Déplacez la logique complexe dans des propriétés calculées ou des méthodes séparées qui retournent View. Cela améliore la lisibilité et permet à SwiftUI de déterminer plus précisément quelles parties de la hiérarchie ont changé. Divisez les grands bodies en sous-composants avec des limites de responsabilité claires.

Deuxième règle : n'utilisez pas body pour effectuer du travail. Chargement de données, opérations réseau, écritures en base de données — tout cela doit se produire en dehors de body, dans des tâches (tasks), des modificateurs onChange ou via ObservableObject. body est destiné uniquement à la déclaration de l'interface.

Troisième règle : utilisez la propriété EquatableView ou un protocole Equatable personnalisé pour les Views si la comparaison structurelle standard est insuffisante. Cela permet d'indiquer explicitement à SwiftUI quand une View enfant nécessite un redessin et d'éviter les appels inutiles à body.

Quatrième règle : si body contient des calculs complexes (formatage, filtrage, tri) — utilisez @State pour la mise en cache du résultat ou déplacez les calculs dans une méthode séparée appelée depuis onChange. Des calculs répétés dans body à chaque mise à jour d'état sont une cause fréquente de ralentissement des animations.

Cinquième règle : pour les listes (List, ForEach) assurez des identifiants stables via le paramètre id. Sans identité stable, ForEach recrée tous les éléments à tout changement, appelant body pour chacun d'eux, même si un seul élément a changé.

Questions Fréquentes

Qu'est-ce que body dans SwiftUI ?

body est la propriété calculée du protocole View qui retourne le contenu à afficher. C'est la seule exigence obligatoire du protocole. Le type de retour est some View, ce qui permet à SwiftUI d'optimiser la hiérarchie au moment de la compilation.

Body peut-elle être appelée plusieurs fois ?

Oui, SwiftUI appelle body à chaque changement d'état (@State, @Binding, @ObservedObject) ou de données d'entrée. C'est un comportement normal pour un framework déclaratif. SwiftUI optimise la fréquence des appels via le mécanisme d'identité et la comparaison Equatable.

Pourquoi body retourne-t-elle some View au lieu d'un type concret ?

some View est un type opaque qui cache l'implémentation concrète. Le compilateur fixe le type au moment de la compilation, garantissant des performances d'appel direct. Cela offre de la flexibilité : vous pouvez changer le type de retour sans modifier la signature.

Peut-on retourner nil depuis body ?

Non, body ne peut pas être optionnelle — le type de retour some View n'autorise pas nil. Si vous devez masquer un élément conditionnellement, utilisez une logique conditionnelle dans @ViewBuilder ou retournez EmptyView, qui ne prend pas de place dans la hiérarchie.

Le nombre de modificateurs affecte-t-il les performances de body ?

Chaque modificateur crée une nouvelle couche ModifiedContent, augmentant la profondeur de la hiérarchie. Pour la plupart des écrans (jusqu'à 50 modificateurs), l'impact est négligeable. Un nombre excessif de modificateurs (centaines) peut ralentir le diffing. Regroupez les modificateurs associés dans des extensions personnalisées.

Résumé

  • body est la propriété calculée obligatoire du protocole View qui définit le contenu de l'écran
  • some View est un type de retour opaque qui cache l'implémentation concrète au code appelant
  • @ViewBuilder est appliqué implicitement à body pour prendre en charge la logique conditionnelle et les éléments multiples
  • body ne doit pas contenir d'effets secondaires — c'est une déclaration d'interface pure
  • SwiftUI optimise les appels à body via le mécanisme d'identité et la comparaison Equatable
  • Divisez les grands bodies en sous-composants pour de meilleures performances et lisibilité
  • AnyView augmente la surcharge — utilisez @ViewBuilder et Group au lieu de l'effacement de type

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