View in English

  • Global Nav Open Menu Global Nav Close Menu
  • Apple Developer
Search
Cancel
  • Apple Developer
  • News
  • Discover
  • Design
  • Develop
  • Distribute
  • Support
  • Account
Only search within “”

Quick Links

5 Quick Links

Vidéos

Ouvrir le menu Fermer le menu
  • Collections
  • Sujets
  • Toutes les vidéos
  • À propos

Retour à WWDC25

  • À propos
  • Résumé
  • Transcription
  • Code
  • Plantez le décor avec SwiftUI dans visionOS

    Découvrez de nouvelles API passionnantes pour améliorer les fenêtres, les volumes et les espaces immersifs de votre app visionOS. Affinez le comportement de vos scènes lorsqu'elles sont relancées ou verrouillées. Faites en sorte que les volumes s'adaptent à leur environnement grâce aux marges de découpe et aux alignements automatiques. Diffusez du contenu immersif de votre Mac vers Vision Pro. Améliorez vos apps UIKit existantes en intégrant des volumes et des espaces immersifs.

    Chapitres

    • 0:00 - Introduction
    • 2:11 - Lancement et verrouillage
    • 8:15 - Améliorations volumétriques
    • 15:58 - Espace immersif
    • 22:16 - Scene bridging
    • 24:01 - Étapes suivantes

    Ressources

    • Adopting best practices for persistent UI
    • Canyon Crosser: Building a volumetric hike-planning app
    • Petite Asteroids: Building a volumetric visionOS game
    • Tracking accessories in volumetric windows
      • Vidéo HD
      • Vidéo SD

    Vidéos connexes

    WWDC25

    • Mieux ensemble : SwiftUI et RealityKit
    • Nouveautés dans les widgets
    • Nouveautés du rendu Metal pour les apps immersives
  • Rechercher dans cette vidéo…

    Bonjour, je m’appelle Miguel, ingénieur de l’équipe SwiftUI. Dans cette vidéo, nous allons découvrir les nouvelles fonctionnalités qui ont été intégrées aux scènes dans visionOS 26. Et peut-être apprendrons-nous à mettre en scène les nôtres.

    visionOS comporte trois types de scènes : les fenêtres, les volumes et les espaces immersifs. Les apps peuvent combiner ces éléments pour créer des expériences uniques et passionnantes.

    Aujourd’hui, nous verrons de nouvelles API qui s’appliquent aux trois types, dont certaines sont plus axées sur les volumes et les espaces immersifs. Mes amis Maks, Amanda et Trevor travaillent sur des améliorations passionnantes de BOTanist, un jeu qui consiste à aider un robot à faire pousser de belles plantes dans un jardin flottant.

    Pour ma part, je travaille sur ma propre app, en créant des scènes et des décors pour aider nos amis robots à donner vie aux personnages de Shakespeare et à se lancer dans le monde du théâtre.

    Lorsque j’ouvre mon app, je suis accueilli par un écran de sélection d’une scène. Créons-en une nouvelle.

    Je peux planter le décor en déplaçant le BOTanist tout autour de la scène.

    Je peux ainsi demander à un ami robot de reconstituer mes pièces préférées, comme Robo et Juliet.

    Voyons comment je peux améliorer mon app avec les nouvelles API de scène de visionOS 26.

    Nous allons examiner les nouvelles API de cycle de vie permettant de définir les comportements lors du lancement et du verrouillage des fenêtres dans les salles.

    Ensuite, je présenterai de nouvelles améliorations volumétriques qui s’adaptent à l’environnement des gens.

    Puis, j’ajouterai un RemoteImmersiveSpace pour prévisualiser ma scène sur Apple Vision Pro à partir d’une app macOS.

    Ensuite, pour les apps UIKit existantes, nous terminerons en ajoutant ces ces expériences volumétriques et immersives exceptionnelles grâce aux nouvelles API de Scene Bridging.

    Commençons donc par le lancement et le verrouillage.

    visionOS 26 intègre certaines API de cycle de vie macOS qui vous seront très utiles. Nous aborderons les API pour gérer la restauration de scène et le lancement des apps, ainsi qu’une API pour créer des fenêtres uniques.

    Dans visionOS 26, les utilisateurs peuvent conserver des fenêtres, des volumes et même les nouveaux widgets en les verrouillant dans des pièces particulières de leur environnement physique.

    Ainsi, le contenu virtuel est plus présent dans leur espace. Ces fenêtres verrouillées sont liées à la pièce dans laquelle elles ont été utilisées.

    Revenez dans cette pièce plus tard, et les fenêtres reprennent vie.

    La restauration de scènes avec verrouillage est géniale. Je peux garder toutes mes fenêtres et y revenir quand je veux.

    En général, les gens s’attendent à pouvoir verrouiller toutes leurs fenêtres, puis à ce que le système les rétablisse. Donc, préférez la restauration pour la plupart des scènes. Le système le fera automatiquement pour vous.

    Toutefois, garder certaines fenêtres dans cet état n’est pas toujours la meilleure solution.

    Envisagez de désactiver la restauration de scène pour les éléments provisoires, comme l’écran d’accueil, les interfaces contextuelles, par exemple, les fenêtres d’outils liées à un état particulier de l’app, ou encore les actions uniques, comme la fenêtre de connexion.

    J’ai ajouté un mode immersif à mon app pour que les gens puissent apprécier pleinement notre robot préféré. La barre d’outils flotte devant vous dans une fenêtre distincte, ce qui donne un accès pratique aux commandes de la scène pendant votre immersion.

    Notez que les espaces immersifs ne sont pas restaurés.

    Ainsi, lorsque vous reviendrez dans cette pièce, l’espace immersif ne sera pas reconstitué.

    Toutefois, si quelqu’un avait verrouillé la fenêtre des outils dans son espace, elle s’afficherait seule, sans aucun élément à modifier.

    Je peux éviter cet état inattendu en ajoutant le modificateur restorationBehavior(.disabled) à mon WindowGroup pour désactive la restauration et le verrouillage de la fenêtre des outils.

    Quand vous retournez dans la pièce par la suite, la fenêtre supplémentaire ne revient pas.

    Le lancement de l’app affiche la première fenêtre pour un nouveau départ.

    Dans UIKit, vous pouvez désactiver la restauration de vos interfaces en utilisant la nouvelle propriété .systemDisconnection de l’API destructionConditions. Consultez la documentation pour en savoir plus.

    Dans certains cas, votre app peut bénéficier d’un changement dynamique de la scène par laquelle commencer.

    Par exemple, je veux ajouter une fenêtre de bienvenue au premier lancement de l’app pour saluer les gens avant la sélection de la scène.

    Pour personnaliser la fenêtre à afficher au lancement en fonction de l’état de mon app, je peux utiliser le modificateur defaultLaunchBehavior.

    Je vais donner la priorité à la fenêtre d’accueil en la marquant comme présentée, si c’est la première fois que l’app est lancée.

    Je peux désactiver cette valeur une fois que cette fenêtre s’affiche, car je n’aurai plus besoin d’afficher la fenêtre.

    Notez que le rôle de la fenêtre de lancement choisie doit correspondre à la propriété de rôle de session de scène par défaut préférée dans le manifeste de scène d’app de votre fichier Info.plist.

    Cela signifie que, si je définis mon rôle de session de scène par défaut sur Fenêtre, seules les scènes de fenêtre seront prises en compte par le système lors du lancement de l’app.

    Dans ce cas, les volumes seront ignorés, même si j’essaie de les hiérarchiser avec defaultLaunchBehavior. Assurez-vous donc de faire correspondre la scène souhaitée avec ce rôle de session.

    Le modificateur defaultLaunchBehavior a plusieurs fonctionnalités qui peuvent nous être utiles.

    J’ai parlé du fait que je ne veux pas que le panneau d’outils revienne lorsque je reviens dans une pièce, et que je pourrais utiliser restorationBehavior pour résoudre ce problème. J’ai un problème similaire ici.

    Actuellement, si je ferme l’espace immersif en appuyant sur la couronne et en fermant la fenêtre Outils, je constate que cette fenêtre revient en relançant l’app.

    Nous nous retrouvons dans cet état inattendu comme pour une restauration.

    Au lieu de cela, je dois reprendre l’app à partir d’un état sécurisé en commençant par une fenêtre de création d’étape.

    Je peux y parvenir en ajoutant le modificateur defaultLaunchBehavior(.suppressed) à ma fenêtre d’outils. Il indique au système de ne pas rétablir cette fenêtre lors du redémarrage de l’app à partir de la vue d’accueil.

    En général, vous devez configurer le .suppressed defaultLaunchBehavior sur les scènes secondaires pour éviter de bloquer les utilisateurs dans un état inattendu.

    Dans UIKit, vous pouvez obtenir le même comportement en ajoutant l’option userInitiatedDismissal aux destructionConditions de votre UIScene.

    visionOS 26 prend également en charge la création de fenêtres uniques.

    Ces fenêtres ne peuvent pas être dupliquées. Une seule instance peut exister à la fois.

    Tout comme sur le Mac, vous les déclarez en utilisant l’API Window au lieu de WindowGroup.

    Utilisez-les pour éviter la duplication d’interfaces importantes, comme une fenêtre de jeu ou un appel vidéo.

    Ou utilisez-les pour fournir des fonctionnalités supplémentaires qui ne nécessitent pas plus d’une instance.

    Je n’ai pas besoin de plusieurs instances de la fenêtre d’accueil. Je vais la remplacer par une fenêtre unique.

    Mais, je vais garder le volume de la scène principale en tant que WindowGroup pour pouvoir créer plusieurs scènes simultanément.

    Génial. Le cycle de vie de mon app n’a jamais été aussi performant. Nous avons personnalisé les fenêtres qui doivent s’afficher lors du verrouillage et du lancement de l’app. Nous nous sommes assurés de garder nos fenêtres uniques lorsque cela avait du sens.

    De nombreuses améliorations ont été apportées aux volumes dans visionOS 26 pour vous aider à approfondir vos volumes.

    Je vais parler de la nouvelle fonctionnalité d’alignement de surface, des avancées des présentations et de l’API Clipping Margins.

    Allons-y !

    Nouveauté visionOS 26 : les utilisateurs peuvent adapter des fenêtres et des volumes à leur environnement physique. Ils peuvent y parvenir en déplaçant doucement la fenêtre près de la surface. Pour les fenêtres restaurables, c’est ce qui les verrouille pour la persistance.

    Les utilisateurs peuvent fixer l’arrière des fenêtres sur des surfaces verticales, comme un mur. Ils peuvent également fixer le bas des volumes à des surfaces horizontales, comme le sol ou une table.

    Les widgets, une nouveauté de visionOS 26, peuvent s’adapter à l’un ou l’autre format.

    Pour en savoir plus sur l’ajout de widgets à votre app visionOS, regardez « What’s in widgets ». Pour les fenêtres et les volumes, vous pouvez obtenir des informations sur l’événement d’alignement.

    Avec mon app, je peux aligner le volume à un tableau et l’ancrer horizontalement.

    C’est un début. Cependant, j’aimerais que la scène soit plus présente dans mon espace. Je veux que le robot se tienne directement sur la table lorsque le volume est aligné sur celle-ci.

    Nous pouvons obtenir des informations sur l’état d’alignement avec la nouvelle API SurfaceSnappingInfo.

    L’API nous donne une propriété isSnapped simple pour déterminer l’état général d’alignement de notre fenêtre.

    Pour des cas d’utilisation plus avancés, nous pouvons obtenir la classification ARKit de la surface alignée. Notez que ce niveau de détail nécessite l’autorisation de l’utilisateur. Voyons cela de plus près.

    Pour activer les informations détaillées sur les surfaces alignées, je dois d’abord définir la clé « Application Wants Detailed Surface Info » sur YES, ainsi que « Privacy World-Sensing Usage-Description » avec une description à afficher lors de la demande d’autorisation.

    Ces deux clés peuvent être définies dans le fichier Info.plist de l’app.

    Une fois terminé, je peux modifier le code.

    Ici, j’ai la surfaceSnappingInfo de l’environnement.

    Dans onChange, je vérifie si la scène est actuellement alignée. Et je vérifie si je suis autorisé à accéder à la classification de la surface d’alignement.

    La vérification de l’autorisationStatus va automatiquement demander l’autorisation à la personne si nécessaire.

    Lorsque je suis aligné à une table, je dois cacher la plate-forme sous la scène. J’utilise une variable d’état pour garder cette information.

    Avec ces changements, je peux aligner mon volume à une table, ce qui permet au robot d’opérer pleinement dans mon environnement. Génial !

    J’ai fait en sorte que, lorsque je marche autour de la table, les murs qui me gênent soient masqués, afin de toujours pouvoir voir l’intérieur de mon volume.

    Pour ce faire, j’ai réagi aux changements de point de vue de la scène à l’aide du modificateur onVolumeViewpointChange.

    Découvrez comment Owen l’a ajouté à BOTanist dans « Dive deep into volumes and immersive spaces » de la WWDC24 pour en savoir plus.

    Je veux aussi que les utilisateurs puissent placer de nouveaux accessoires tout autour de la scène. Je peux ajouter une fenêtre contextuelle dans la barre d’outils de mon volume avec différents accessoires à ajouter.

    Génial ! Je peux enfin recréer La Tragédie du Roi Gear.

    Auparavant, les présentations n’étaient prises en charge que dans les fenêtres.

    Avec visionOS 2.4, vous pouvez imbriquer différents éléments d’interface, comme afficher des popovers depuis des feuilles, ou encore afficher des menus déroulants à partir d’éléments décoratifs.

    Avec visionOS 26, les présentations bénéficient d’un tout nouvel ensemble de sources. Vous êtes libre de présenter à partir de volumes, d’ornements de volumes, de pièces jointes à RealityViews ou directement dans RealityKit à l’aide du composant PresentationComponent.

    Pour en savoir plus sur l’utilisation des présentations dans RealityKit avec les pièces jointes et le PresentationComponent, regardez « Better together: SwiftUI and RealityKit ». Cela ne se limite pas à un petit sous-ensemble. Tous les types de présentation sont disponibles : menus, infobulles, popovers, feuilles, alertes et boîtes de dialogue de confirmation.

    Consultez la documentation pour découvrir comment créer ces présentations avec SwiftUI.

    Ces présentations bénéficient toutes d’un traitement visuel spécial pour rester visibles lorsqu’elles sont masquées par du contenu 3D.

    Par défaut, la présentation se fond subtilement dans le contenu occultant.

    Vous pouvez personnaliser cette option afin que la présentation s’affiche clairement ou soit masquée derrière le contenu occultant.

    Utilisez les options subtile, prominent ou none pour la personnaliser.

    Ces options peuvent être appliquées aux présentations à l’aide du modificateur presentationBreakthroughEffect.

    Pour les éléments autres que les présentations, vous pouvez obtenir le même effet avec un modificateur breakthroughEffect.

    Avec les présentations, je peux ajouter une UI personnalisée où je veux. Essayons d’en ajouter d’autres.

    J’ai ajouté un autre menu contextuel pour changer le décor de la scène. Je peux ainsi transporter notre robot loin de l’ancien théâtre et sur une île tropicale. Parfait pour la tempête !

    Cet ensemble a beaucoup de potentiel. Cependant, je pense que nous pouvons l’améliorer. Que diriez-vous d’une cascade ? Oh, et quelques nuages orageux.

    Je veux aussi m’assurer qu’ils n’encombrent pas le centre de l’action. Je peux utiliser les nouvelles marges de rognage pour cela.

    Avec Volumes, la nouvelle API PreferredWindowClippingMargins vous permet d’afficher du contenu en dehors des limites de votre scène.

    Ce contenu n’est pas interactif. Vous ne devez l’utiliser qu’à des fins esthétiques.

    Notez que ces limites peuvent ne pas être accordées par le système. Pour en tenir compte, lisez les marges accordées avec la variable d’environnement windowClippingMargins.

    Voyons comment ça marche.

    Je peux spécifier les marges de rognage souhaitées avec l’API preferredWindowClippingMargins. Ici, je veux des marges en bas.

    Je m’assure de convertir mon maxWaterfallHeight, qui est en mètres, en points en multipliant par le facteur pointsPerMeter que j’ai obtenu de PhysicalMetric.

    Je lis ensuite les marges accordées à l’aide de la variable d’environnement windowClippingMargins.

    Je peux ainsi mettre à l’échelle ma cascade pour qu’elle s’affiche dans les marges.

    Je prends le minimum des marges et de la hauteur de la cascade pour m’assurer que nous affichons toujours l’ensemble du modèle de cascade, indépendamment de ce qui a été accordé.

    Et voilà. Ça a l’air beaucoup mieux. Les nuages ajoutent une atmosphère orageuse agréable, et la cascade s’affiche sous la base sans déplacer le contenu vers le haut, ce qui permet de garder l’attention sur l’île et son robot.

    J’espère que le BOTanist est bien huilé.

    Notre dernière production théâtrale semble maintenant plus réelle que jamais. Grâce aux marges d’alignement et de rognage, le contenu s’adapte à notre espace physique. Et grâce aux présentations, je peux créer des interfaces puissantes pour créer la scène parfaite.

    Voyons maintenant ce que je peux faire pour améliorer l’expérience immersive de mon app.

    Les espaces immersifs vous offrent des expériences spatiales tout autour de vous. Et visionOS 26 offre de nouvelles façons d’exploiter encore plus les espaces immersifs.

    Je vais vous présenter un événement de recentrage de monde, de nouvelles fonctionnalités pour les styles d’immersion, un espace immersif à distance sur macOS et des avancées dans les espaces immersifs basés sur Compositor pour le rendu avec Metal. Lorsqu’ils se trouvent dans leur espace, les utilisateurs peuvent appuyer longuement sur la Digital Crown pour recentrer l’expérience de l’app autour d’eux.

    Si votre app utilise des données ARKit, cela peut invalider les positions que vous auriez pu stocker pour une utilisation ultérieure.

    Vous pouvez écouter l’événement de recentrage de monde avec le nouveau modificateur de vue onWorldRecenter pour être alerté à ce sujet.

    Ceci est très utile pour recalculer et stocker les positions en fonction du nouveau système de coordonnées.

    visionOS 26 propose aussi de nouvelles options de personnalisation pour les différents styles d’immersion disponibles dans les espaces immersifs.

    Le style d’immersion progressive est un excellent moyen de présenter partiellement un espace immersif tout en gardant les gens ancrés dans le monde réel.

    Le contenu immersif est présenté dans un portail dont la taille peut être modifiée en tournant la Digital Crown.

    Cette plage d’immersion peut être personnalisée dans le style d’immersion progressive.

    Dans visionOS 26, vous pouvez aussi personnaliser le format d’image de ce portail. Vous pouvez utiliser le format paysage existant ou le nouveau format portrait.

    Choisissez le format portrait pour les expériences verticales, notamment quand vous adaptez vos jeux iPhone sur Apple Vision Pro. Il est également recommandé pour les contenus ayant beaucoup de mouvements, car un environnement stable dans le champ de vision périphérique aide les utilisateurs à se sentir plus à l’aise.

    Vous pouvez spécifier ce rapport hauteur/largeur à l’aide d’un paramètre au style progressif, comme vous le feriez avec la plage d’immersion.

    En plus du style progressif, il y a aussi une nouvelle personnalisation pour les espaces immersifs dans le style d’immersion mixte.

    Lorsque vous définissez le style d’immersion sur mixte, le contenu de l’espace immersif se fond dans l’environnement des gens.

    C’est le style par défaut dans mon app.

    Dans visionOS 26, le contenu de l’espace immersif peut également se fondre dans les environnements système. Cela signifie que je peux regarder la dernière production de mon robot sur la lune.

    Utilisez le modificateur de scène immersiveEnvironmentBehavior avec le comportement coexist pour autoriser cette opération.

    Faites-le si votre espace immersif mixte n’exige pas que les utilisateurs soient conscients de leur environnement réel.

    J’adore les accessoires que j’ai ajoutés à mon app, mais je suis convaincu que les utilisateurs voudront ajouter leurs modèles pour créer de nouvelles scènes. Ils peuvent créer ces modèles dans leurs apps macOS préférées.

    Pour permettre l’utilisation de ces modèles sur leur Mac, j’ai porté mon app sur macOS avec les mêmes fonctionnalités de création de scènes.

    Pour gagner du temps, ce serait vraiment pratique de pouvoir visualiser les scènes dans un espace immersif directement depuis macOS, sans devoir les transférer vers visionOS à chaque fois.

    visionOS 26 et macOS Tahoe ajoutent RemoteImmersiveSpaces pour m’aider à faire exactement cela. Grâce aux espaces immersifs à distance, vous pouvez utiliser CompositorLayer pour rendre du contenu avec Metal à l’aide du code et des ressources de l’app sur votre Mac, puis l’afficher sous forme d’expérience immersive sur votre Vision Pro.

    Voyons comment cela fonctionne dans mon app.

    Sur mon app Mac, j’ai créé un nouvel espace immersif à l’aide de Metal et ajouté un bouton « Prévisualiser dans Vision Pro ».

    En cliquant dessus, je peux sélectionner un appareil Vision Pro cible.

    Sur mon Vision Pro, j’accepte la demande de connexion.

    Et voilà, mon ImmersiSpace s’ouvre et je peux voir les nouveaux accessoires que j’ai ajoutés au dernier spectacle de mon robot.

    Pour cela, j’ai ajouté une scène RemoteImmersiveSpace contenant mon CompositorLayer.

    Celle-ci sera présentée sur visionOS, tandis que le reste de mes scènes, comme ma scène principale, seront toujours présentées directement sur le Mac.

    Pour en savoir plus sur l’adaptation de CompositorLayer et ARKitSession à un appareil Vision Pro distant, consultez « What’s new in Metal rendering for immersive apps ». L’utilisation de CompositorLayer dans mon espace immersif distant me donne beaucoup de possibilités pour créer des expériences immersives avec Metal.

    Mais, CompositorLayer n’est pas une vue, et il ne peut pas être utilisé dans des contextes qui nécessitent des vues, comme mon ImmersiveContent.

    Jusqu’à présent, cela signifiait que les variables d’environnement et les modificateurs de vue n’étaient pas disponibles pour CompositorLayer.

    visionOS 26 ajoute un nouveau type de générateur CompositorContent, qui vous permet d’exploiter toute la puissance de SwiftUI avec CompositorLayer.

    Vous pouvez accéder aux variables d’environnement, ajouter des modificateurs ou utiliser des variables d’état, comme vous le feriez avec les vues SwiftUI.

    CompositorContent fournit de nombreuses variables d’environnement utiles, telles que scenePhase et openWindow, ainsi que certains modificateurs, comme onImmersionChange et onWorldRecenter.

    Tous ces éléments rendent CompositorLayer beaucoup plus performant, tant dans les espaces immersifs distants que dans les espaces classiques qui s’exécutent directement sur visionOS.

    La mise à niveau de mon app pour utiliser CompositorContent m’a permis de revisiter certains des modificateurs Immersive Space à ma disposition et de voir comment les appliquer à mon app.

    Voilà donc les dernières nouveautés en matière d’espaces immersifs. Nous avons un événement de recentrage du monde, de nouvelles personnalisations pour les styles d’immersion, des espaces immersifs depuis Mac avec RemoteImmersiveSpace et CompositorContent.

    Mon app est incroyable avec toutes ces fonctionnalités. En fait, je pense que je vais ajouter certaines de ces expériences volumétriques intéressantes à d’autres apps.

    Mais, certaines de mes apps ont été développées avec UIKit, qui ne prend pas en charge les volumes et les espaces immersifs. Mais désormais, c’est possible grâce au Scene Bridging.

    Scene Bridging vous permet de faire passer vos apps UIKit existantes dans une nouvelle dimension en ajoutant des volumes SwiftUI et des espaces immersifs.

    Prenons l’exemple de Safari. Il utilise les vues SwiftUI, mais est basé sur le cycle de vie UIKit.

    Safari utilise pleinement la fonctionnalité Scene Bridging pour sa nouvelle fonctionnalité de navigation spatiale.

    Voyons comment nous pouvons l’utiliser.

    Pour relier une scène SwiftUI à mon app UIKit, je commence par créer un type de classe qui étend UIHostingSceneDelegate.

    Avec ce type, je peux déclarer mes scènes SwiftUI dans la propriété rootScene en utilisant la syntaxe familière du corps de scène.

    Je peux demander cette scène comme je le ferais pour n’importe quelle autre scène UIKit en créant une UISceneSessionActivationRequest.

    Dans ce cas, je passe ma classe de délégué d’hébergement, qui déclare mes scènes, et l’ID de la scène que je souhaite ouvrir.

    Il ne vous reste plus qu’à envoyer cette demande avec activateSceneSession.

    Vous pouvez aussi répondre à des événements externes en définissant votre classe de délégué d’hébergement dans configurationForConnecting.

    Cette API est également fournie avec une API AppKit correspondante pour connecter les scènes SwiftUI à vos apps AppKit macOS existantes.

    Mon app tire pleinement parti des nouvelles fonctionnalités de visionOS 26, comme le verrouillage sur place, l’alignement sur des surfaces et l’ouverture à distance depuis un Mac. J’ai hâte de montrer tout cela à mes amis.

    Jetez un coup d’œil à vos apps. Vérifiez vos scènes et assurez-vous qu’elles tirent parti des fonctionnalités de verrouillage et de restauration.

    Adaptez vos scènes à l’environnement des personnes grâce aux marges d’alignement et de rognage.

    Et plongez dans le contenu de votre app macOS sur Vision Pro grâce à des espaces immersifs à distance.

    Le rideau tombe, mais dans notre app, le spectacle continue, une scène à la fois. Merci de votre attention !

    • 4:10 - Disabling restoration

      // Disabling restoration
      
      WindowGroup("Tools", id: "tools") {
          ToolsView()
      }
      .restorationBehavior(.disabled)
    • 4:36 - Disabling restoration in UIKit

      // Disabling restoration
      
      windowScene.destructionConditions = [
          .systemDisconnection
      ]
    • 5:02 - Specifying launch window

      // Specifying launch window
      
      @AppStorage("isFirstLaunch") private var isFirstLaunch = true
      
      var body: some Scene {
          WindowGroup("Stage Selection", id: "selection") {
              SelectionView()
          }
      
          WindowGroup("Welcome", id: "welcome") {
              WelcomeView()
                  .onAppear {
                      isFirstLaunch = false
                  }
          }
          .defaultLaunchBehavior(isFirstLaunch ? .presented : .automatic)
      
          // ...
      }
    • 6:39 - "suppressed" behavior

      // "suppressed" behavior
      
      WindowGroup("Tools", id: "tools") {
          ToolsView()
      }
      .restorationBehavior(.disabled)
      .defaultLaunchBehavior(.suppressed)
    • 7:44 - Unique window

      // Unique window
      
      @AppStorage("isFirstLaunch") private var isFirstLaunch = true
      
      var body: some Scene {
          // ...
      
          Window("Welcome", id: "welcome") {
              WelcomeView()
                  .onAppear {
                      isFirstLaunch = false
                  }
          }
          .defaultLaunchBehavior(isFirstLaunch ? .presented : .automatic)
      
          WindowGroup("Main Stage", id: "main") {
              StageView()
          }
      
          // ...
      }
    • 10:24 - Surface snapping

      // Surface snapping
      
      @Environment(\.surfaceSnappingInfo) private var snappingInfo
      @State private var hidePlatform = false
      
      var body: some View { 
          RealityView { /* ... */ }
          .onChange(of: snappingInfo) {
              if snappingInfo.isSnapped &&
                  SurfaceSnappingInfo.authorizationStatus == .authorized
              {
                  switch snappingInfo.classification {
                      case .table:
                          hidePlatform = true
                      default:
                          hidePlatform = false
                  }
              }
          }
      }
    • 14:41 - Clipping margins

      // Clipping margins
      
      @Environment(\.windowClippingMargins) private var windowMargins
      @PhysicalMetric(from: .meters) private var pointsPerMeter = 1
      
      var body: some View {
          RealityView { content in
              // ...
              waterfall = createWaterfallEntity()
              content.add(waterfall)
          } update: { content in
              waterfall.scale.y = Float(min(
                  windowMargins.bottom / pointsPerMeter,
                  maxWaterfallHeight))
              // ...
          }
          .preferredWindowClippingMargins(.bottom, maxWaterfallHeight * pointsPerMeter)
      }
    • 16:44 - World recenter

      // World recenter
      
      var body: some View {
          RealityView { content in
              // ...
          }
          .onWorldRecenter {
              recomputePositions()
          }
      }
    • 17:58 - Progressive immersion style

      // Progressive immersion style
      
      @State private var selectedStyle: ImmersionStyle = .progressive
      
      var body: some Scene {
          ImmersiveSpace(id: "space") {
              ImmersiveView()
          }
          .immersionStyle(
              selection: $selectedStyle,
              in: .progressive(aspectRatio: .portrait))
      }
    • 18:37 - Mixed immersion style

      // Mixed immersion style
      
      @State private var selectedStyle: ImmersionStyle = .progressive
      
      var body: some Scene {
          ImmersiveSpace(id: "space") {
              ImmersiveView()
          }
          .immersionStyle(selection: $selectedStyle, in: .mixed)
          .immersiveEnvironmentBehavior(.coexist)
      }
    • 20:14 - Remote immersive space

      // Remote immersive space
      
      // Presented on visionOS
      RemoteImmersiveSpace(id: "preview-space") {
          CompositorLayer(configuration: config) { /* ... */ }
      }
      
      // Presented on macOS
      WindowGroup("Main Stage", id: "main") {
          StageView()
      }
    • 20:48 - 'CompositorLayer' is a 'CompositorContent'

      // 'CompositorLayer' is a 'CompositorContent'
      
      struct ImmersiveContent: CompositorContent {
          @Environment(\.scenePhase) private var scenePhase
      
          var body: some CompositorContent {
              CompositorLayer { renderer in
                  // ...
              }
              .onImmersionChange { oldImmersion, newImmersion in
                  // ...
              }
          }
      }
    • 23:00 - Scene bridging

      // Scene bridging
      
      import UIKit
      import SwiftUI
      
      // Declare the scenes
      class MyHostingSceneDelegate: NSObject, UIHostingSceneDelegate {
          static var rootScene: some Scene {
              WindowGroup(id: "my-volume") {
                  ContentView()
              }
              .windowStyle(.volumetric)
          }
      }
      
      // Create a request for the scene
      let requestWithId = UISceneSessionActivationRequest(
          hostingDelegateClass: MyHostingSceneDelegate.self, id: "my-volume")!
      
      // Send a request
      UIApplication.shared.activateSceneSession(for: requestWithId)
    • 0:00 - Introduction
    • Dans visionOS 26, vous pouvez utiliser de nouvelles API pour les scènes, les fenêtres, les volumes et les espaces immersifs. Elles vous permettront de créer des apps plus dynamiques et interactives. Parmi les nouvelles fonctionnalités, citons les API de cycle de vie, les améliorations volumétriques, « RemoteImmersiveSpace » pour la prévisualisation sur Apple Vision Pro et les API Scene Bridging pour les apps UIKit.

    • 2:11 - Lancement et verrouillage
    • Les nouvelles API de visionOS 26 vous permettent de gérer le lancement des apps et la restauration des scènes. Vous pouvez ainsi créer des expériences plus immersives. Les utilisateurs peuvent désormais verrouiller des fenêtres, des volumes et des widgets dans des pièces spécifiques. Le contenu virtuel reste ainsi présent dans leur environnement physique. Le système rétablit de lui-même les fenêtres verrouillées dès qu’un utilisateur entre dans la pièce concernée. Cependant, vous pouvez bloquer cette restauration pour certains éléments temporaires, comme les écrans de bienvenue ou les menus contextuels en utilisant le modificateur « restorationBehavior(.disabled) ». Vous pouvez aussi personnaliser le démarrage de l’app en sélectionnant de manière dynamique la fenêtre à afficher selon l’état de l’app, grâce au modificateur « defaultLaunchBehavior ». Les fenêtres uniques, qui ne peuvent pas être dupliquées, sont désormais gérées par l’API Window, ce qui empêcher la duplication d’interfaces importantes, telles que les fenêtres de jeu ou les appels vidéo.

    • 8:15 - Améliorations volumétriques
    • Plusieurs améliorations majeures ont été apportées aux volumes. Vous pouvez utiliser l’API « SurfaceSnappingInfo » pour surveiller quand les fenêtres et les volumes s’alignent sur des surfaces physiques, telles que des murs et des tables. Cette fonctionnalité offre des expériences plus immersives, car vous pouvez ajuster la scène en fonction de l’état d’alignement, par exemple en masquant des plateformes ou en ajustant des accessoires. ARKit peut fournir des détails sur la surface alignée à votre app, avec l’autorisation de l’utilisateur. La mise à jour étend également les fonctionnalités de présentation. Les éléments peuvent désormais provenir de différentes sources dans les volumes, les ornements et RealityKit, et bénéficier de traitements visuels spéciaux qui garantissent leur visibilité derrière le contenu 3D. Personnalisez le traitement visuel grâce au modificateur « presentationBreakthroughEffect ». De plus, grâce à la nouvelle API Clipping Margins, vous pouvez afficher du contenu non interactif en dehors des limites de la scène, ce qui améliore les effets visuels, tels que les cascades ou les nuages, tout en garantissant que le contenu principal reste centré et dégagé. Consultez la variable d’environnement « windowClippingMargins » pour vérifier si le système a accordé les marges.

    • 15:58 - Espace immersif
    • Vous pouvez désormais réagir à un évènement de recentrage du monde, qui permet aux utilisateurs de recalibrer l’expérience de l’app autour d’eux. Utilisez le modificateur de vue « onWorldRecent » pour écouter cet évènement, puis recalculez et enregistrez les positions en fonction du nouveau système de coordonnées. visionOS 26 offre également de nouvelles options de personnalisation pour les styles d’immersion. Le style d’immersion progressive inclut désormais le format portrait, ce qui permet des expériences verticales et améliore le confort lors de la lecture de contenus à fort mouvement. Le style d’immersion mixte permet désormais au contenu de s’intégrer de manière transparente à l’environnement du système. Vous créez ainsi des scénarios plus immersifs. Utilisez le modificateur de scène « immersiveEnvironmentBehavior » avec le comportement « coexist » pour activer cette fusion. Grâce à « RemoteImmersiveSpaces », vous pouvez désormais importer vos apps sur macOS et de visualiser des environnements immersifs directement sur l’Apple Vision Pro. Cette fonctionnalité accélère les itérations et la collaboration. Utilisez « CompositorLayer » pour rendre du contenu avec Metal sur votre Mac, puis affichez-le sur votre Apple Vision Pro. L’arrivée du générateur « CompositorContent » permet de tirer pleinement parti de SwiftUI avec « CompositorLayer ». Cette nouveauté simplifie considérablement la création et le pilotage d’expériences immersives, que ce soit à distance ou en local. Elle offre également un accès pratique aux variables d’environnement, la possibilité d’ajouter des modificateurs et l’utilisation de variables d’état.

    • 22:16 - Scene bridging
    • La fonctionnalité Scene Bridging de visionOS 26 vous permet d’ajouter des volumes SwiftUI et des espaces immersifs à des apps UIKit existantes. Grâce à l’extension de « UIHostingSceneDelegate », vous pouvez créer des scènes SwiftUI et les demander à l’aide de « UISceneSessionActivationRequest ». Les apps, telles que Safari peuvent ainsi utiliser la navigation spatiale et d’autres apps peuvent aussi tirer parti des nouvelles fonctionnalités de visionOS.

    • 24:01 - Étapes suivantes
    • L’app de démonstration permet aux utilisateurs de concevoir des scènes verrouillées et alignées sur des surfaces, qu’ils peuvent ensuite déverrouiller et manipuler à distance depuis leur Mac. Prenez le temps d’analyser vos apps pour vous assurer qu’elles exploitent au maximum ces nouvelles fonctionnalités.

Developer Footer

  • Vidéos
  • WWDC25
  • Plantez le décor avec SwiftUI dans visionOS
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • App Store
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Fonts
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Open Source
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Sample Code
    • Tutorials
    • Downloads
    • Forums
    • Videos
    Open Menu Close Menu
    • Support Articles
    • Contact Us
    • Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Get the Apple Developer app.
    Copyright © 2025 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines