-
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…
-
-
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.