
-
Nouveautés dans UIKit
Modernisez votre app avec les dernières API de UIKit, notamment la prise en charge améliorée de la barre de menus, le suivi automatique des observations, une nouvelle méthode de mise à jour de l'interface utilisateur et des améliorations des animations. Nous verrons également comment inclure des scènes SwiftUI dans votre app UIKit et explorerons Symbols SF, les sélecteurs de couleurs HDR, et bien plus encore.
Chapitres
- 0:00 - Introduction
- 0:59 - Nouveau système de conception
- 2:29 - Conteneurs et adaptabilité
- 3:21 - Barre de menus
- 9:58 - Améliorations architecturales
- 10:21 - Suivi automatique des observations
- 12:33 - Nouvelle méthode de mise à jour de l’interface utilisateur
- 15:45 - Améliorations des animations
- 17:45 - Mises à jour des scènes
- 18:55 - Prise en charge des couleurs HDR
- 20:38 - Notifications Swift
- 21:20 - Migrer vers un cycle de vie basé sur des scènes
- 22:40 - Prise en charge d’OpenURL pour les URL de fichiers
- 23:17 - Symbols SF 7
- 25:13 - Étapes suivantes
Ressources
Vidéos connexes
WWDC25
- Créez un UIKit app avec le nouveau design
- Découvrez le nouveau système de conception
- Quoi de neuf dans Symbols SF 7
- Rendez votre app UIKit plus flexible
- Sublimez le design de votre app iPad
WWDC24
WWDC23
WWDC21
-
Rechercher dans cette vidéo…
Bonjour et bienvenue dans « Nouveautés dans UIKit ». Je m’appelle Dima, Responsable Ingénierie dans l’équipe UIKit. D’iOS et iPadOS à tvOS, visionOS et Mac Catalyst, UIKit reste la base de vos apps, avec encore plus d’améliorations. Je vais d’abord vous présenter la prise en charge par UIKit du nouveau système de conception. Ensuite, j’aborderai les améliorations apportées au contenu de votre app afin de s’adapter à différents appareils et formats d’écran. Puis, je présenterai les nouvelles API UIKit pour la barre de menus, cet élément familier de macOS désormais disponible sur iPadOS. Je vais parler des principales avancées dans l’architecture UIKit, en revenant sur les principes clés. Pour finir, je conclurai par les améliorations générales apportées au framework. Le nouveau système de conception offre un aspect dynamique aux matériaux et contrôles du système. Un nouveau matériau occupe une place centrale : Liquid Glass. Translucide, dynamique et expressif, il offre des effets tels que la réflexion spéculaire et la réfraction. Les barres et champs de recherche, les alertes, les popovers, les vues scindées et tous les composants standard UIKit ont été repensés pour intégrer ce nouveau matériau.
Les transitions de navigation sont désormais fluides et interruptibles, ce qui rend votre app plus réactive.
Les utilisateurs peuvent tout de suite interagir avec le contenu, sans attendre la fin de l’animation.
De plus, pour améliorer votre UI et l’adapter au nouveau design, nous avons introduit des outils tels que l’affichage en extension de l’arrière-plan, qui permet à votre contenu d’apparaître sous la plaque en verre de la barre latérale, pour une continuité visuelle.
Il existe également un matériau à effet verre pour vos propres composants personnalisés et le nouvel effet de bordure défilante, qui permet à votre contenu de s’estomper élégamment lorsqu’il défile sous les plaques en verre, afin de mieux voir les boutons de la barre et d’autres commandes.
Pour un guide pratique complet sur la nouvelle présentation de vos apps UIKit, regardez la vidéo « Build a UIKit app with the new design ». Pour découvrir le nouveau design, consultez « Get to know the new design system ». Voici maintenant les améliorations apportées au contenu de vos apps pour s’adapter à différents appareils et formats d’écran. Sous iOS 26, UISplitViewController bénéficie d’une prise en charge optimale des inspecteurs. Un inspecteur fournit des détails supplémentaires sur un contenu sélectionné. Par exemple, Aperçu utilise un inspecteur pour afficher les métadonnées à côté de la photo, dans la colonne secondaire.
Vous pouvez désormais aussi redimensionner les colonnes en faisant glisser les séparateurs du contrôleur de vue scindée. Lorsque vous utilisez le pointeur, sa forme s’adapte pour indiquer les directions dans lesquelles une colonne peut être redimensionnée. Pour en savoir plus sur les améliorations apportées aux contrôleurs de vue conteneur, et pour rafraîchir vos connaissances sur les concepts généraux de disposition tels que les marges et les zones de sécurité, regardez la vidéo « Make your UIKit app more flexible ». Parlons ensuite du menu : iOS 26 introduit la barre de menus de macOS sur l’iPad. Désormais, un balayage du haut de l’écran affiche le menu complet de votre app, même sans clavier physique. C’est un excellent moyen d’accéder rapidement aux fonctionnalités de votre app.
La barre de menus prend en charge toutes les fonctionnalités du menu : images, sous-menus, sections intégrées, coches, etc. Elle doit afficher toutes les commandes de votre app, même celles qui n’ont pas de raccourci clavier. Les commandes indisponibles restent visibles, mais sont désactivées, afin que les utilisateurs voient toutes les fonctionnalités de votre app.
Les apps utilisent toujours UIMenuBuilder pour personnaliser leurs menus principaux, et sous iOS 26, UIKit introduit plusieurs API pour créer des barres de menus plus performantes. Je vais commencer par la configuration du système de menu principal. Cette API permet aux apps de personnaliser les commandes système initialement fournies dans le menu principal. Lorsque vous utilisez l’API de configuration, votre app bénéficie d’éléments de menu supplémentaires préconfigurés et localisés, comme la nouvelle commande d’activation/désactivation des inspecteurs. Elle vous permet aussi d’indiquer à l’avance les éléments à inclure ou à omettre. Vous pouvez aussi configurer et styliser en profondeur des groupes d’éléments individuels, par exemple, en optimisant les commandes Rechercher selon les besoins de votre app. Enfin, fournissez à l’avance un bloc UIMenuBuilder pour l’ajout d’éléments personnalisés, ce qui permet à votre app et à ses extensions de partage d’utiliser le même code pour définir les raccourcis clavier pris en charge. Voici un exemple d’utilisation d’une configuration de système de menu principal. D’abord, je crée un objet de configuration. Je précise ensuite les commandes que mon app doit afficher par défaut dans le menu principal. Par exemple, je déclare la prise en charge des commandes d’impression système.
Je vais désactiver certaines commandes par défaut, comme le nouveau bouton bascule de la sous-fenêtre d’inspection. La configuration me permet de définir des styles communs pour les commandes par défaut, comme la conversion des commandes de recherche du système en un seul élément Recherche. C’est très utile pour les apps de photos ou de musique, où l’on recherche des contenus plutôt que du texte. Enfin, je peux définir la configuration dans le menu principal afin qu’il soit créé avec l’ensemble initial d’éléments préférés. Je peux également fournir un gestionnaire de build, qui sera appelé à la place de buildMenuWithBuilder. Le gestionnaire permet d’accéder à un UIMenuBuilder qui a été amélioré sous iOS 26 avec des méthodes pratiques et plus efficaces, des performances accrues et de meilleurs diagnostics.
Notez que la définition d’une configuration entraînera la reconstruction de la barre de menus. Idéalement, votre app ne devrait définir la configuration qu’une seule fois et le plus tôt possible, par exemple dans application(_:didFinishLaunchingWithOptions:). iOS et macOS 26 introduisent des actions et menus standard supplémentaires dans la barre de menus. performClose est associée à Cmd-W et ferme votre fenêtre par défaut, mais elle peut aussi fermer d’autres éléments de votre app, comme les onglets d’un navigateur web. La commande de menu « Nouveau à partir du presse-papier » permet de créer des documents à partir du contenu du presse-papiers, sans déclencher d’alerte Coller. Le menu newItem introduit sous iOS 26 est un emplacement idéal pour cette commande. Les actions standard d’alignement du texte, d’activation/désactivation de la barre latérale et de l’inspecteur peuvent désormais être personnalisées dans vos apps. Par défaut, les raccourcis clavier se répètent en appuyant longuement sur les touches, mais vous pouvez personnaliser ce comportement avec la propriété repeatBehavior sur UIKeyCommand.
Cette propriété peut aussi être définie pour chaque répondeur avec validateCommand. Ceci est particulièrement important pour les actions destructrices comme la touche Supprimer qui supprime un e-mail, afin d’éviter de les déclencher accidentellement de manière répétée. Parfois, certaines parties de la barre de menus doivent afficher un contenu dynamique selon l’élément sélectionné ou une scène de fenêtre. Par exemple, les apps de navigation telles que Safari peuvent afficher l’historique du profil de navigation actuel dans le menu Historique.
Pour ce faire, utilisez le nouvel élément de menu de report basé sur le focus, qui remplit ses éléments à partir de la chaîne de répondeurs. Lorsque vous construisez votre menu principal, créez un UIDeferredMenuElement avec le focus et attribuez-lui un identifiant pour le différencier. Ensuite, insérez-le dans le menu principal.
Lorsque l’élément de report doit être exécuté, UIKit parcourt la chaîne de répondeurs jusqu’à trouver un répondeur capable de fournir des éléments. Dans cet exemple, le contrôleur de vue du navigateur remplace provider For DeferredMenuElement pour fournir les éléments de l’historique du profil actuel.
Il vérifie l’identifiant de l’élément de report pour l’élément browserHistory et renvoie un Fournisseur pour charger les éléments du menu Historique. Les éléments de report basés sur le focus sont un excellent moyen de maintenir la barre de menus à jour avec des commandes sans touche, sans reconstructions coûteuses du système de menu principal. En plus des éléments personnalisés de votre app, le système fournit automatiquement plusieurs entrées de menu. Votre app dispose d’un raccourci clavier permettant d’ouvrir ses réglages dans l’app Réglages. Pour les apps basées sur des documents, le menu Éléments récents affiche les documents récents. Le système complète également le menu Fenêtre avec des commandes en mosaïque, y compris une liste de toutes les scènes ouvertes pour votre app. Donnez un titre à chaque scène pour aider les utilisateurs à les distinguer. Enfin, voici quelques points à garder à l’esprit lorsque vous créez votre barre de menus. Dans les apps UIKit, les barres de menus définies dans les storyboards ne sont plus prises en charge. Les apps ne se lancent pas avec les menus dans les storyboards, il faut les implémenter par programmation.
Vous devez aussi vous assurer que les fonctionnalités de votre app restent accessibles sans la barre de menus, car celle-ci ne sera pas toujours présente. Pour en savoir plus sur la création d’une barre de menus efficace pour votre app, regardez la vidéo « Elevate the design of your iPad app ». Pour une vue d’ensemble du menu principal UIKit, consultez « Take your iPad apps to the next level ». Nous continuons de faire évoluer UIKit en ajoutant des fonctionnalités adaptées aux modèles modernes, aux bonnes pratiques et une interopérabilité SwiftUI plus poussée. iOS 26 ne fait pas exception, et je vais vous présenter des améliorations géniales apportées à l’architecture. La première grande amélioration est la prise en charge intégrée des objets Swift Observable dans UIKit.
UIKit intègre désormais Swift Observation au cœur de son architecture : dans les méthodes de mise à jour comme layoutSubviews(), il suit automatiquement tout Observable référencé, relie les dépendances et invalide les vues appropriées, sans définition manuelle setNeedsLayout requise. Vous pouvez déployer cela sur iOS 18 en ajoutant la clé UIObservationTrackingEnabled à votre fichier Info.plist. Sous iOS 26, cela est activé par défaut. Je vais présenter quelques exemples concrets de suivi automatique des observations.
Ici, j’ai un contrôleur de vue de liste de messages avec une étiquette UILabel qui indique les messages non lus.
Il est soutenu par un objet de modèle Observable avec deux propriétés : une valeur booléenne qui contrôle l’affichage du statut et la chaîne spécifiant le statut. Dans viewWillLayoutSubviews(), j’utilise le modèle Observable pour mettre à jour l’alpha de l’étiquette afin de l’afficher ou de la masquer, et définir son texte. Lors de la première disposition, UIKit renseigne l’étiquette et, grâce au suivi automatique des observations, enregistre les dépendances sur showStatus et statusText. Toute modification de ces propriétés invalide la vue et relance viewWillLayoutSubviews(), ce qui permet de synchroniser l’étiquette sans code supplémentaire. Voici un autre exemple d’utilisation des objets Observable avec UIKit, qui démontre les avantages du suivi automatique des observations lors de la configuration des cellules dans une UICollectionView. Je soutiens chaque cellule de la liste avec un ListItemModel observable contenant une icône, un titre et un sous-titre. Dans la fonction de rappel du fournisseur de cellules, je désactive une cellule, récupère son modèle et lui attribue un configurationUpdateHandler. Ce gestionnaire prend en charge le suivi des observations, donc UIKit établit automatiquement des dépendances avec tous les objets Observable que j’utilise à l’intérieur.
Dans le gestionnaire, je renseigne et applique une configuration de contenu de liste à l’aide du modèle d’élément de liste observable. C’est tout ! Désormais, toute modification des propriétés du modèle alors que la cellule est visible entraîne la réexécution du gestionnaire par UIKit et la mise à jour de la cellule. Avec l’ajout du suivi automatique des caractéristiques et des observations, UIKit offre désormais une méthode de mise à jour polyvalente pour prendre en charge ces fonctionnalités.
Nous introduisons une nouvelle méthode, updateProperties(), dans UIView et UIViewController.
Elle s’exécute juste avant layoutSubviews(), mais est indépendante : cela permet d’invalider des propriétés sans forcer la disposition, et inversement, pour éviter des passes supplémentaires et obtenir des mises à jour plus précises.
updateProperties() complète layoutSubviews() sans toutefois la remplacer. Utilisez-la pour renseigner du contenu, appliquer un style ou configurer des comportements.
Elle suit automatiquement tout Observable que vous lisez et vous pouvez la déclencher manuellement en appelant setNeedsUpdateProperties(). Je vais présenter un exemple concret d’utilisation de cette nouvelle méthode.
Ici, j’ai un objet Observable BadgeModel qui stocke le nombre affiché dans une vue badge. Le contrôleur de vue pour l’élément bouton-barre est pris en charge par un BadgeModel.
Dans updateProperties(), j’utilise la nouvelle API de badge sur l’élément du bouton de la barre et extrait le nombre directement du modèle. Désormais, chaque fois que l’objet du modèle Observable change, updateProperties() s’exécute et met à jour le badge.
En utilisant updateProperties() pour configurer la vue au lieu de layoutSubviews(), j’évite de réexécuter le code lors d’événements non liés, tels que le redimensionnement, ce qui réduit le travail inutile et améliore les performances. Afin de mieux comprendre comment updateProperties() s’intègre aux autres méthodes de mise à jour, je vais expliquer le fonctionnement du cycle de mise à jour de UIKit.
Voici comment UIKit met à jour les vues avant de les afficher à l’écran. La passe de disposition est la première étape. UIKit parcourt la hiérarchie des vues de haut en bas, met à jour les caractéristiques de chaque vue, puis appelle layoutSubviews(). Si, suite à l’exécution de cette passe, d’autres vues requièrent une disposition, la passe de disposition se répète jusqu’à ce que tout soit disposé.
Une fois la disposition définie, UIKit exécute le traitement d’affichage, en appelant la méthode draw sur chaque vue et en répétant l’opération jusqu’à ce que toutes les vues n’aient plus besoin d’être affichées. Une fois les deux passes terminées, le frame suivant peut être rendu et affiché à l’écran.
Et voici comment s’intègre la nouvelle fonction de rappel updateProperties(). Lors de la passe de disposition descendante, UIKit exécute updateProperties() immédiatement après la mise à jour des caractéristiques et juste avant layoutSubviews(). On peut considérer que layoutSubviews() comprend deux étapes : d’abord les mises à jour des propriétés, puis la logique de disposition habituelle. Étant donné que la collection de caractéristiques est mise à jour avant l’exécution de updateProperties(), vous pouvez la lire en toute sécurité là. Et comme elle précède toujours layoutSubviews(), vous pouvez y invalider la disposition, et la passe de disposition s’exécutera de suite après.
Afin de compléter la nouvelle fonctionnalité de suivi des observations et la nouvelle méthode updateProperties(), nous avons amélioré le fonctionnement des animations dans UIKit.
Avant de commencer, je vais expliquer comment fonctionne une mise à jour manuelle sous iOS 18 et les versions antérieures. Dans une fermeture d’animation UIView, les nouvelles valeurs sont d’abord définies sur les objets Observable, puis layoutIfNeeded() est appelé sur les vues qui dépendent de ces objets. Ces deux étapes sont nécessaires, car la première étape entraîne une invalidation, et la deuxième étape effectue la mise à jour et crée des animations. La gestion manuelle des dépendances entre les propriétés et les vues est source d’erreurs et peut entraîner un nombre excessif ou insuffisant de mises à jour ou d’animations. iOS 26 propose une nouvelle option d’animation pour les UIViews appelée flushUpdates. Lorsque cette option est activée, UIKit applique les mises à jour en attente juste avant le début de l’animation, puis à nouveau à la fin de celle-ci. Vous n’avez donc plus besoin d’appeler layoutIfNeeded(). Pour que flushUpdates fonctionne, les modifications d’état invalides doivent uniquement être effectuées dans la fermeture d’animation. Je vais présenter un exemple d’utilisation de flushUpdates. Tout d’abord, transmettez flushUpdates en tant qu’option à UIView.animate, puis modifiez l’objet Observable dans la fermeture. Toute vue utilisant cet objet Observable dans une méthode de mise à jour effectuera automatiquement la mise à jour nécessaire. flushUpdates ne se limite pas aux animations pilotées par Observable.
Voici un exemple d’utilisation pour animer automatiquement les modifications des contraintes de disposition automatique. Dans la fermeture flushUpdates, je définis une nouvelle constante pour l’une des contraintes existantes, et j’active et désactive d’autres contraintes. Les vues dépendantes s’animent automatiquement pour s’adapter à leur nouvelle position et taille. Je vais maintenant expliquer comment nous avons rendu l’utilisation de SwiftUI et UIKit plus fluide dans la même app. Les scènes SwiftUI sont désormais prises en charge dans les apps UIKit avec un nouveau protocole délégué. Cela favorise l’adoption progressive de SwiftUI et permet également aux apps UIKit de tirer parti des espaces et des volumes immersifs sur visionOS.
Imaginez une app de méditation qui présente une scène de jardin zen : dans une fenêtre 2D standard sur iPhone et iPad, et sous forme d’espace immersif sur visionOS. Je présente cet espace immersif en implémentant le nouveau protocole UIHostingSceneDelegate avec une scène SwiftUI racine.
L’utilisation d’un délégué de scène d’hébergement est similaire à celle de tout autre délégué de scène. Il suffit de définir le type de classe déléguée dans UISceneConfiguration lorsqu’une nouvelle scène se connecte.
Vous pouvez demander par programmation une scène SwiftUI spécifique au délégué d’hébergement en transmettant son identifiant.
Dans cet exemple, je demande zengardenspace. Enfin, je vais présenter quelques améliorations générales apportées à UIKit, en commençant par les améliorations du rendu HDR. Avec iOS 26, le HDR n’est plus réservé aux images : les couleurs bénéficient désormais du même traitement, pour mettre en valeur votre UI ou offrir de nouvelles expériences.
UIColor permet désormais de spécifier une couleur SDR de base et une valeur d’exposition, ajustant automatiquement la luminosité selon les capacités de l’écran. Ici, je crée une couleur HDR rouge avec une exposition réglée à deux fois et demie la valeur maximale du blanc SDR. Vous pouvez désormais activer la sélection des couleurs HDR dans UIColorPickerViewController et UIColorWell. Pour cela, définissez une exposition maximale en fonction des capacités de rendu de votre app. Ici, j’ai défini l’exposition linéaire maximale du sélecteur de couleurs à deux fois la valeur maximale du blanc SDR.
Sous iOS 18, UIImageView passe intelligemment du HDR au SDR, pour garantir que le contenu essentiel de l’interface utilisateur reste bien visible. Sous iOS 26, ce comportement s’étend aux vidéos, et votre propre contenu personnalisé peut également y participer. Veuillez utiliser la nouvelle caractéristique UITraitHDRHeadroomUsage pour surveiller quand votre contenu HDR doit revenir au SDR. Pour en savoir plus sur le HDR, regardez les vidéos « Use HDR for dynamic image experiences in your app » et « Support HDR images in your app ».
Grâce à l’API NSNotification.Name, UIKit sous iOS 26 représente chaque notification sous la forme d’un type NotificationCenter.Message dédié. Cela vous fournit une valeur fortement typée pour enregistrer les observateurs et récupérer les détails des événements. Voici un exemple d’ajustement de la disposition lorsque le clavier apparaît : Je m’inscris au type de notification keyboardWillShow, puis, dans le gestionnaire, j’extrais la durée de l’animation et le frame du clavier directement à partir du message. Enfin, j’anime mes contraintes avec ces valeurs, sans avoir besoin de rechercher des userInfo ni de procéder à une conversion manuelle. À chaque nouvelle version, l’évolution continue d’UIKit vous offre des API modernes et robustes adaptées aux bonnes pratiques actuelles. À mesure que vous les adoptez, nous abandonnons progressivement les anciennes méthodes.
L’adoption d’UIScene rend vos apps portables et très flexibles. Nous retirerons de nombreuses API axées sur UIApplication.
Les rappels UIApplicationDelegate hérités et UIApplicationLaunchOptionKeys ne s’appliquent plus, et seul l’initialiseur init(windowScene:) pour UIWindow subsiste. Tous les autres initialiseurs sont obsolètes. Dans la version ultérieure à iOS 26, toute app UIKit développée avec le dernier SDK devra utiliser le cycle de vie UIScene, sinon elle ne pourra pas être lancée.
Adoptez le cycle de vie UIScene partout, pas seulement dans les apps multi-fenêtres. Pour en savoir plus sur la façon de procéder, lisez la note technique : « Migrating to the UIKit scene-based life cycle ». Pour en savoir plus sur la manière d’optimiser la flexibilité de votre app, notamment grâce aux nouvelles API qui aident à migrer depuis UIRequiresFullScreen, regardez la vidéo « Make your UIKit app more flexible ».
Les apps traitant divers types de documents doivent souvent lancer des visionneuses externes. Sous iOS 26, la méthode openURL existante accepte désormais les URL de fichiers, ce qui permet de transférer des documents non pris en charge nativement par votre app. Si une app par défaut existe pour ce type de fichier, le système la lance et lui transmet votre URL. Si ce n’est pas le cas, openURL renvoie « false », vous permettant de gérer la solution de secours, par exemple en utilisant un contrôleur d’aperçu rapide.
Symbols SF a été amélioré sous iOS 26. Symbols SF 7 permet de dessiner des symboles, en commençant par deux nouveaux effets. Draw Off, tout comme l’effet Disappear, utilise l’animation de dessin pour masquer un symbole. Draw On, comme Appear, affiche un symbole masqué en le dessinant.
Les symboles peuvent désormais prendre en charge le dessin variable, un nouveau mode pour les valeurs variables. Cela dessine des valeurs arbitraires le long d’un tracé, comme pour cet indicateur de progression. Vous pouvez aussi l’utiliser avec la transition automatique du contenu des symboles pour animer des valeurs variables.
Les transitions Magic Replace peuvent également effectuer des animations spéciales entre certains symboles. Par exemple, cette transition entre le symbole cercle et le symbole coche remplie a pour effet de remplir le cercle et de dessiner la coche. Les nouvelles animations de dessin sont très utiles pour les boutons. C’est pourquoi UIKit dispose d’une API permettant d’adopter les transitions de contenu des symboles dans UIButton.
Utilisez la nouvelle propriété symbolContentTransition dans UIButton.Configuration pour spécifier une transition de contenu de symbole, telle que « remplace ». Lorsque le symbole du bouton change, par exemple, lorsque son état de sélection bascule, UIKit effectue la transition. Symbols SF 7 introduit aussi d’autres fonctionnalités, comme la nouvelle option de mode de rendu des couleurs. Les apps peuvent spécifier Dégradé pour colorer leurs symboles à l’aide de dégradés générés automatiquement au lieu de couleurs unies.
Pour savoir comment personnaliser entièrement les dessins et les dégradés, regardez la vidéo « What’s new in SF Symbols 7 ». Pour rafraîchir vos connaissances sur l’utilisation des effets de symbole pour l’animation, consultez « Animate symbols in your app ».
Et ensuite ? Compilez votre app à l’aide du SDK iOS 26. Vérifiez comment votre app réagit à la nouvelle conception et affinez vos interfaces utilisateur et votre style selon la nouvelle esthétique. Utilisez des conteneurs standard tels que UISplitViewController et UITabBarController pour prendre en charge les dispositions flexibles. Implémentez les menus de votre app en utilisant les nouvelles API de menus. Adoptez la méthode updateProperties et le suivi des observations afin de rationaliser votre code et d’améliorer les performances. Merci ! J’ai hâte de voir comment vous allez utiliser ces améliorations pour rendre vos apps encore plus performantes et conviviales !
-
-
4:56 - Main menu system configuration
// Main menu system configuration var config = UIMainMenuSystem.Configuration() // Declare support for default commands, like printing config.printingPreference = .included // Opt out of default commands, like inspector config.inspectorPreference = .removed // Configure the Find commands to be a single "Search" element config.findingConfiguration.style = .search
-
5:39 - Main menu system build configuration
// Main menu system configuration // Have the main menu system build using this configuration, and make custom additions. // Call this early, e.g. in application(_:didFinishLaunchingWithOptions:), and call it once UIMainMenuSystem.shared.setBuildConfiguration(config) { builder in builder.insertElements([...], afterCommand: #selector(copy(_:))) let deleteKeyCommand = UIKeyCommand(...) builder.replace(command: #selector(delete(_:)), withElements: [deleteKeyCommand]) }
-
7:01 - Keyboard shortcut repeatability
// Keyboard shortcut repeatability let keyCommand = UIKeyCommand(...) keyCommand.repeatBehavior = .nonRepeatable
-
7:43 - Focus-based deferred menu elements (App Delegate)
// Focus-based deferred menu elements extension UIDeferredMenuElement.Identifier { static let browserHistory: Self = .init(rawValue: "com.example.deferred-element.history") } // Create a focus-based deferred element that will display browser history let historyDeferredElement = UIDeferredMenuElement.usingFocus( identifier: .browserHistory, shouldCacheItems: false ) // Insert it into the app’s custom History menu when building the main menu builder.insertElements([historyDeferredElement], atEndOfMenu: .history)
-
8:06 - Focus-based deferred menu elements (View Controller)
// Focus-based deferred menu elements class BrowserViewController: UIViewController { // ... override func provider( for deferredElement: UIDeferredMenuElement ) -> UIDeferredMenuElement.Provider? { if deferredElement.identifier == .browserHistory { return UIDeferredMenuElement.Provider { completion in let browserHistoryMenuElements = profile.browserHistoryElements() completion(browserHistoryMenuElements) } } return nil } }
-
10:54 - Using an Observable object and automatic observation tracking
// Using an Observable object and automatic observation tracking @Observable class UnreadMessagesModel { var showStatus: Bool var statusText: String } class MessageListViewController: UIViewController { var unreadMessagesModel: UnreadMessagesModel var statusLabel: UILabel override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() statusLabel.alpha = unreadMessagesModel.showStatus ? 1.0 : 0.0 statusLabel.text = unreadMessagesModel.statusText } }
-
11:48 - Configuring a UICollectionView cell with automatic observation tracking
// Configuring a UICollectionView cell with automatic observation tracking @Observable class ListItemModel { var icon: UIImage var title: String var subtitle: String } func collectionView( _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath ) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) let listItemModel = listItemModel(for: indexPath) cell.configurationUpdateHandler = { cell, state in var content = UIListContentConfiguration.subtitleCell() content.image = listItemModel.icon content.text = listItemModel.title content.secondaryText = listItemModel.subtitle cell.contentConfiguration = content } return cell }
-
13:27 - Using automatic observation tracking and updateProperties()
// Using automatic observation tracking and updateProperties() @Observable class BadgeModel { var badgeCount: Int? } class MyViewController: UIViewController { var model: BadgeModel let folderButton: UIBarButtonItem override func updateProperties() { super.updateProperties() if let badgeCount = model.badgeCount { folderButton.badge = .count(badgeCount) } else { folderButton.badge = nil } } }
-
16:57 - Using the flushUpdates animation option to automatically animate updates
// Using the flushUpdates animation option to automatically animate updates // Automatically animate changes with Observable objects UIView.animate(options: .flushUpdates) { model.badgeColor = .red }
-
17:23 - Automatically animate changes to Auto Layout constraints with flushUpdates
// Automatically animate changes to Auto Layout constraints UIView.animate(options: .flushUpdates) { // Change the constant of a NSLayoutConstraint topSpacingConstraint.constant = 20 // Change which constraints are active leadingEdgeConstraint.isActive = false trailingEdgeConstraint.isActive = true }
-
18:07 - Setting up a UIHostingSceneDelegate
// Setting up a UIHostingSceneDelegate import UIKit import SwiftUI class ZenGardenSceneDelegate: UIResponder, UIHostingSceneDelegate { static var rootScene: some Scene { WindowGroup(id: "zengarden") { ZenGardenView() } #if os(visionOS) ImmersiveSpace(id: "zengardenspace") { ZenGardenSpace() } .immersionStyle(selection: .constant(.full), in: .mixed, .progressive, .full) #endif } }
-
18:28 - Using a UIHostingSceneDelegate
// Using a UIHostingSceneDelegate func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { let configuration = UISceneConfiguration(name: "Zen Garden Scene", sessionRole: connectingSceneSession.role) configuration.delegateClass = ZenGardenSceneDelegate.self return configuration }
-
18:41 - Requesting a scene
// Requesting a scene func openZenGardenSpace() { let request = UISceneSessionActivationRequest( hostingDelegateClass: ZenGardenSceneDelegate.self, id: “zengardenspace")! UIApplication.shared.activateSceneSession(for: request) }
-
19:18 - HDR color support
// Create an HDR red relative to a 2.5x peak white let hdrRed = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0, linearExposure: 2.5)
-
19:50 - HDR color picking
// Support picking HDR colors relative to a // maximum peak white of 2x colorPickerController.maximumLinearExposure = 2.0
-
20:06 - Mixing SDR and HDR content
// Mixing SDR and HDR content registerForTraitChanges([UITraitHDRHeadroomUsageLimit.self]) { traitEnvironment, previousTraitCollection in let currentHeadroomLimit = traitEnvironment.traitCollection.hdrHeadroomUsageLimit // Update HDR usage based on currentHeadroomLimit’s value }
-
20:54 - Adopting Swift notifications
// Adopting Swift notifications override func viewDidLoad() { super.viewDidLoad() let keyboardObserver = NotificationCenter.default.addObserver( of: UIScreen.self for: .keyboardWillShow ) { message in UIView.animate( withDuration: message.animationDuration, delay: 0, options: .flushUpdates ) { // Use message.endFrame to animate the layout of views with the keyboard let keyboardOverlap = view.bounds.maxY - message.endFrame.minY bottomConstraint.constant = keyboardOverlap } } }
-
24:26 - Using a symbol content transition to automatically animate symbol updates
// Using a symbol content transition to automatically animate symbol updates var configuration = UIButton.Configuration.plain() configuration.symbolContentTransition = UISymbolContentTransition(.replace)
-
-
- 0:00 - Introduction
Découvrez les améliorations apportées à UIKit pour iOS, iPadOS, tvOS, visionOS et Mac Catalyst. Cette vidéo présente le nouveau système de conception, les conteneurs et l’adaptabilité, les API pour la barre de menus sous iPadOS et Mac Catalyst, les principales avancées architecturales et les améliorations générales du framework.
- 0:59 - Nouveau système de conception
Le nouveau système de conception inclut Liquid Glass : un style translucide et dynamique qui rafraîchit les composants UIKit standard et améliore les transitions de navigation. UIKit dispose également d’une nouvelle API pour appliquer Liquid Glass à votre interface utilisateur personnalisée.
- 2:29 - Conteneurs et adaptabilité
iOS 26 améliore « UISplitViewController » avec des inspecteurs pour l’affichage détaillé du contenu et le redimensionnement dynamique des colonnes.
- 3:21 - Barre de menus
iOS 26 améliore la barre de menus sur iPad, désormais accessible d’un simple balayage depuis le haut de l’écran, pour offrir un accès rapide aux fonctionnalités des apps sans clavier physique. La barre de menus doit toujours afficher toutes les commandes d’app, même celles qui sont désactivées ou sans raccourci clavier. Personnalisez la barre de menus à l’aide de la nouvelle API pour la configuration du menu principal et implémentez des menus dynamiques basés sur la vue active. Des actions standard comme « Fermer » et « Nouveau à partir du presse-papiers » sont introduites. Les actions d’alignement du texte et d’activation/désactivation de la barre latérale et de l’inspecteur peuvent désormais être personnalisées. Assurez-vous que les actions sont disponibles dans votre app, sans dépendre de la barre de menus.
- 9:58 - Améliorations architecturales
UIKit continue d’évoluer avec de nouvelles fonctionnalités pour les modèles modernes, les bonnes pratiques et une interopérabilité SwiftUI plus poussée.
- 10:21 - Suivi automatique des observations
UIKit suit désormais automatiquement les objets observables référencés dans les méthodes de mise à jour comme « layoutSubviews » ; plus besoin d’appels manuels à « setNeedsLayout ». Cette fonctionnalité est activée par défaut dans iOS 26 et vous pouvez la déployer sur iOS 18 à l’aide de la clé Info.plist « UIObservationTrackingEnabled ». Les modifications apportées aux propriétés du modèle Observable qui mettent à jour les éléments de l’interface utilisateur déclenchent automatiquement l’invalidation de la vue et les réexécutions des méthodes de mise à jour pertinentes, ce qui permet de synchroniser l’interface utilisateur sans code supplémentaire.
- 12:33 - Nouvelle méthode de mise à jour de l’interface utilisateur
UIKit introduit une nouvelle méthode, « updateProperties », disponible dans « UIView » et « UIViewController ». Cette méthode s’exécute indépendamment avant « layoutSubviews » et vous permet de remplir le contenu, d’appliquer un style et de configurer des comportements plus efficacement. « updateProperties » suit automatiquement les observables et peut aussi être déclenchée manuellement en appelant « setNeedsUpdateProperties ». En utilisant cette méthode, vous pouvez éviter les passes de disposition inutiles, ce qui améliore les performances de votre app.
- 15:45 - Améliorations des animations
Dans iOS 26, UIKit introduit « flushUpdates », une option d’animation qui applique automatiquement les mises à jour en attente avant et après les animations ; plus besoin d’appels « layoutIfNeeded » manuels. Cela simplifie le code, réduit les erreurs et fonctionne avec les objets observables et les modifications des contraintes de disposition automatique.
- 17:45 - Mises à jour des scènes
Vous pouvez désormais intégrer des scènes SwiftUI dans les apps UIKit en utilisant le nouveau protocole « UIHostingSceneDelegate ». Créez des apps qui s’adaptent à différents appareils, comme une app de méditation avec un jardin zen en 2D sur iPhone et iPad et une expérience visionOS immersive, en demandant une scène SwiftUI spécifique par programmation.
- 18:55 - Prise en charge des couleurs HDR
Dans iOS 26, UIKit améliore également le rendu HDR au-delà des images pour inclure les couleurs. Créez des couleurs HDR à l’aide de « UIColor » et activez la sélection des couleurs HDR dans les sélecteurs de couleurs. Utilisez la nouvelle caractéristique « UITraitHDRHeadroomUsage » pour surveiller quand votre contenu HDR doit revenir au SDR.
- 20:38 - Notifications Swift
UIKit représente chaque notification avec un type de « NotificationCenter.Message » dédié dans iOS 26. Il fournit ainsi des notifications fortement typées pour faciliter la gestion des évènements, comme le montre un exemple d’ajustement de la disposition lorsque le clavier apparaît.
- 21:20 - Migrer vers un cycle de vie basé sur des scènes
« UIScene » remplace « UIApplication » en tant que norme pour le développement d’apps, rendant les apps plus portables et flexibles. Vous devez adopter le cycle de vie « UIScene » car les méthodes héritées sont obsolètes. De plus, à partir de la version qui suivra iOS 26, les apps qui n’ont pas adopté le cycle de vie de scène ne se lanceront pas.
- 22:40 - Prise en charge d’OpenURL pour les URL de fichiers
La méthode « openURL » permet désormais aux apps de transférer des documents non natifs à des visionneuses par défaut ou d’utiliser des contrôleurs d’aperçu rapide s’il n’existe pas de valeur par défaut.
- 23:17 - Symbols SF 7
Symbols SF 7 propose de nouvelles capacités de dessin, notamment les effets « Draw Off » et « Draw On », le mode Dessin variable pour dessiner des valeurs arbitraires le long d’un chemin, ainsi que des animations de dessin spéciales avec des transitions Magic Replace. UIKit fournit désormais une API pour faciliter l’adoption de ces transitions dans « UIButton », et les symboles peuvent être colorés avec des dégradés générés automatiquement.
- 25:13 - Étapes suivantes
Afin de mettre à jour votre app pour iOS 26 et d’améliorer les performances, compilez avec le nouveau SDK, affinez les interfaces utilisateur pour qu’elles correspondent à la nouvelle conception, utilisez des conteneurs standard et les nouvelles API de menu, et adoptez la méthode « updateProperties » ainsi que le suivi des observations.