SwiftUI : ce que c'est, concepts clés et View Protocol

Auteur : IT Sectr Publié le : 2026-04-30 Temps de lecture : 8 min

SwiftUI est un framework déclaratif d'Apple pour construire des interfaces utilisateur sur toutes les plateformes de l'écosystème. Au lieu de décrire les étapes de manière impérative, le développeur déclare à quoi l'interface doit ressembler et SwiftUI gère son rendu et sa mise à jour. Selon la Apple Developer Documentation (2025), SwiftUI prend en charge iOS 15+, iPadOS 15+, macOS 12+, watchOS 8+ et tvOS 15+ et utilise le View Protocol comme bloc de construction de base pour tous les composants d'interface.

Points clés

  • SwiftUI est un framework déclaratif d'Apple où le développeur décrit l'interface et les mises à jour sont effectuées automatiquement.
  • View Protocol avec la propriété body est la base de tout composant d'interface SwiftUI, renvoyant une description d'écran par composition de vues.
  • Property Wrappers — @State, @Binding, @ObservedObject, @StateObject — gèrent l'état et déclenchent le réaffichage lors des modifications de données.
  • NavigationStack (iOS 16+) est une API de navigation moderne avec des routes type-safe et des transitions déclaratives.
  • Modifier est une chaîne d'appels pour personnaliser l'apparence et le comportement des vues sans héritage de classes.

Qu'est-ce que SwiftUI ?

SwiftUI est un framework déclaratif présenté par Apple en 2019 pour remplacer UIKit dans les nouveaux projets. Au lieu de créer manuellement des instances UIView et de les ajouter à la hiérarchie, le développeur décrit l'interface à travers des structures conformes au protocole View. SwiftUI calcule automatiquement la différence entre l'état actuel et le nouvel état et ne réaffiche que les parties modifiées en utilisant son propre moteur de rendu.

Le framework est écrit en Swift en utilisant des value semantics (structures, pas de classes), ce qui rend les composants d'interface légers et thread-safe. Contrairement à UIKit, où UIViewController peut peser 200+ octets à cause du runtime Objective-C, une SwiftUI View est simplement une structure de quelques octets. Ceci est particulièrement important pour watchOS avec sa mémoire limitée.

Multiplateforme SwiftUI

La même description de View fonctionne sur iPhone, iPad, Mac, Apple Watch, Apple TV et Apple Vision Pro. SwiftUI adapte l'interface à la plateforme : gestes tactiles sur iOS, combinaisons de clavier sur macOS, défilement Digital Crown sur watchOS. Cela réduit le temps de développement pour les entreprises qui publient des applications sur plusieurs plateformes Apple, mais nécessite une configuration supplémentaire pour les éléments spécifiques à chaque plateforme.

View Protocol et le corps de la vue

Dans SwiftUI, chaque écran est une structure qui implémente le protocole View avec une seule exigence : une propriété calculée body de type some View. Le mot-clé some (type opaque) cache le type concret de la vue, permettant à SwiftUI d'optimiser le rendu. À l'intérieur de body, le développeur combine des composants prêts à l'emploi — Text, Image, Button, List — en utilisant ViewBuilder, qui assemble plusieurs vues en une seule.

swift
struct GreetingView: View {
    let name: String

    var var body: some View {
        VStack {
            Text("Bonjour, \(name) !")
                .font(.title)
                .foregroundColor(.blue)
            Image(systemName: "hand.wave")
                .imageScale(.large)
        }
        .padding()
    }
}

Dans l'exemple, VStack (pile verticale) contient Text et Image. La valeur de name est passée via l'initialiseur de la structure — c'est ainsi que fonctionne DI (Dependency Injection) dans SwiftUI sans conteneurs DI externes. Chaque modificateur renvoie une nouvelle vue avec la modification appliquée, sans muter l'originale. Ceci est possible grâce à l'immuabilité des value types.

ViewBuilder et conditionnelles

ViewBuilder est un result builder annoté avec @resultBuilder qui assemble jusqu'à 10 vues en une seule. À l'intérieur de body, on peut utiliser if/else, switch et ForEach sans wrappers supplémentaires. ForEach fonctionne avec des éléments Identifiable — chaque vue reçoit un identifiant unique pour une animation correcte lors de l'insertion/suppression.

Gestion d'état : @State, @Binding, @ObservedObject

Dans SwiftUI, l'état détermine quel contenu est affiché à l'écran. Lorsque l'état change, SwiftUI recrée le body de la vue dépendante et compare le résultat avec le précédent en utilisant un algorithme de diff. Pour stocker l'état, on utilise des property wrappers — chacun résout sa tâche spécifique : état local, connexion avec une vue fille ou modèle de données externe.

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

    var var body: some View {
        VStack {
            Text("Compteur : \(count)")
            Button("Incrémenter") {
                count += 1
            }
        }
    }
}

class UserViewModel: ObservableObject {
    @Published var name = ""
    @Published var age = 0
}

@State stocke une valeur locale simple (Int, String, Bool) dans la structure View. SwiftUI déplace la mémoire de la structure vers un stockage séparé — donc une propriété avec @State peut être mutée même si View est un value type. @ObservableObject est pour les classes avec des propriétés @Published, dont les changements notifient automatiquement SwiftUI de la nécessité de se réafficher.

@Binding et liaison parent-enfant

@Binding crée une liaison bidirectionnelle avec une source de données située dans la vue parent. Le parent passe $variable (projected value), et l'enfant lit et écrit la valeur via le binding. Cela permet de déplacer la saisie de texte ou un interrupteur dans un composant séparé tout en conservant l'état dans le parent. Sans @Binding, chaque changement nécessiterait une closure de callback pour transmettre la nouvelle valeur vers le haut.

Avant iOS 16, la navigation dans SwiftUI était construite sur NavigationView — une API legacy avec un comportement complexe sur iPad (split view, double colonne). À partir d'iOS 16, Apple recommande NavigationStack — une alternative simplifiée avec des routes type-safe. Le développeur définit un enum des routes possibles, et NavigationStack gère automatiquement la pile d'écrans avec prise en charge des deep links et du retour à la racine.

swift
enum Route: Hashable {
    case detail(id: Int)
    case settings
}

struct ContentView: View {
    var var body: some View {
        NavigationStack {
            List {
                NavigationLink("Écran de détail",
                               value: Route.detail(id: 42))
                NavigationLink("Paramètres",
                               value: Route.settings)
            }
            .navigationDestination(for: Route.self) { route in
                switch route {
                case .detail(let id): DetailView(id: id)
                case .settings: SettingsView()
                }
            }
        }
    }
}

Les routes conformes à Hashable permettent d'utiliser n'importe quel type de données pour passer des paramètres. navigationDestination(for:destination:) associe le type de route à la vue cible. L'avantage par rapport à la navigation UIKit est qu'aucun réaffichage n'est nécessaire lors de l'ajout d'une nouvelle route : il suffit d'ajouter un case à l'enum et un handler dans le switch. Les deep links sont traités via processDeepLink sur NavigationStack.

Navigation programmatique

Pour la navigation programmatique (après connexion, minuteur ou réponse du serveur), on utilise @State avec l'initialiseur NavigationLink : NavigationLink(isActive: $isActive). Lorsque isActive = true, la transition s'effectue sans toucher l'utilisateur. Une alternative est le binding du tableau $path dans NavigationStack : $path.append(Route.detail(id: 1)).

View Modifier — personnalisation de l'apparence

Modifier est une méthode qui renvoie une copie modifiée de la vue. Contrairement à UIKit, où la configuration des propriétés se fait par mutation d'une vue existante, SwiftUI crée une nouvelle valeur avec la modification appliquée. L'enchaînement de modificateurs construit l'interface finale à partir de transformations séquentielles : police → padding → couleur → ombre → geste.

Apple fournit plus de 200 modificateurs intégrés. Les plus courants : .font(), .foregroundColor(), .padding(), .background(), .cornerRadius(), .shadow(), .opacity(), .offset(). L'ordre des modificateurs est important : .padding() avant .background() remplit la zone avec le padding, après — seulement la zone intérieure. Les modificateurs personnalisés sont créés via le protocole ViewModifier.

Modificateurs conditionnels et animation

Les modificateurs peuvent être appliqués conditionnellement via l'opérateur ternaire : .foregroundColor(isError ? .red : .primary). Pour l'animation, on utilise .animation(.easeInOut, value: state) — le modificateur d'animation est lié à une propriété d'état spécifique. Lorsque cette propriété change, SwiftUI anime la transition entre l'ancienne et la nouvelle valeur. L'animation fonctionne avec opacity, offset, scale, rotation, la taille et la couleur — chaque propriété a un AnimatableParameter correspondant.

Pour les animations personnalisées, .transition (apparition/disparition) et .matchedGeometryEffect (transition fluide d'un élément entre deux conteneurs) sont disponibles. Ce dernier est utilisé pour les hero animations dans les listes : une icône dans une cellule de liste se transforme en douceur en une grande image sur l'écran de détail.

SwiftUI vs UIKit : comparaison des approches

Le choix entre SwiftUI et UIKit est l'un des premiers dilemmes du développeur iOS. Les deux frameworks sont pris en charge par Apple mais résolvent le problème de construction d'interface de manière fondamentalement différente : SwiftUI déclarativement, UIKit impérativement. La différence se manifeste dans la gestion d'état, la navigation, les performances et la compatibilité.

AspectSwiftUIUIKit
ApprocheDéclarative : quoi afficherImpérative : comment construire
ÉtatProperty Wrappers, réaffichage automatiqueManuel : reloadData, setNeedsLayout
Code UICompact, chaînes de modificateursVerbeux, NSCoder/Storyboard/contraintes
PerformancesÉlevées sur iOS 17+, algorithme de diffPic sur iOS 12–16, contrôle direct
Version minimaleiOS 15+ (support complet)iOS 2+ (toutes versions)

Pour les nouveaux projets avec une version minimale iOS 17, Apple recommande SwiftUI comme framework principal. UIKit reste nécessaire pour les interfaces nécessitant un contrôle fin sur le rendu (UICollectionViewLayout personnalisé, scènes CAAnimation complexes) ou la prise en charge d'iOS 12–14. De nombreux projets utilisent une approche hybride : SwiftUI via UIHostingController est intégré dans une application UIKit, et UIViewRepresentable permet d'utiliser des composants UIKit dans la hiérarchie SwiftUI.

Questions fréquentes

Peut-on utiliser SwiftUI et UIKit dans le même projet ?

Oui, via UIHostingController (SwiftUI dans UIKit) et UIViewRepresentable (UIKit dans SwiftUI). C'est une approche hybride, populaire lors de la migration.

Avec quelle version d'iOS démarrer un projet SwiftUI ?

iOS 17 offre des fonctionnalités complètes : NavigationStack, Observation framework, Swift Charts. iOS 15 est le seuil minimum pour la production.

Pourquoi SwiftUI ne met-il parfois pas à jour l'interface ?

La cause la plus fréquente est la modification d'une propriété @Published sur un thread d'arrière-plan. ObservableObject doit envoyer les modifications sur le main actor : @MainActor class ViewModel.

Comment gérer le debounce lors de l'appui sur un bouton dans SwiftUI ?

Utilisez .debounce via Combine : Button.publisher(for: .tap) .debounce(for: .seconds(0.3), scheduler: RunLoop.main).

SwiftUI prend-il en charge les gestes personnalisés ?

Oui, via les modificateurs Gesture : DragGesture, LongPressGesture, MagnificationGesture, RotationGesture. Combinez-les avec .simultaneousGesture() et .sequenced().

Résumé

  • SwiftUI est un framework déclaratif d'Apple où l'interface est décrite comme une composition de structures View avec des property wrappers pour la gestion d'état.
  • View Protocol avec la propriété calculée body est le point d'entrée unique pour toute vue. ViewBuilder assemble jusqu'à 10 vues en une sans conteneurs supplémentaires.
  • @State, @Binding et @ObservedObject couvrent tous les scénarios de gestion de données : état local, liaison parent-enfant et modèles externes.
  • NavigationStack avec des routes enum type-safe a remplacé NavigationView, ajoutant la prise en charge des deep links et de la navigation programmatique.
  • Modifier est un motif clé de SwiftUI permettant de personnaliser l'apparence des vues via une chaîne d'appels sans héritage.
  • SwiftUI et UIKit coexistent via UIHostingController et UIViewRepresentable, permettant une migration progressive du projet.
  • Pour iOS 17+, Apple recommande SwiftUI comme framework principal ; UIKit reste pour les interfaces personnalisées complexes et la prise en charge des anciennes versions.

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