-
Prepare o ambiente com o SwiftUI no visionOS
Descubra novas APIs para melhorar janelas, volumes e espaços imersivos em seu app para visionOS. Aprimore o comportamento de suas cenas quando forem reativadas ou ancoradas no lugar. Faça com que os volumes se adaptem ao ambiente ao seu redor com margens de corte e ajustes. Reproduza conteúdo imersivo do Mac no Vision Pro. Aprimore seus apps do UIKit com volumes e espaços imersivos.
Capítulos
- 0:00 - Introdução
- 2:11 - Abertura e fixação
- 8:15 - Aprimoramentos para volumes
- 15:58 - Espaço imersivo
- 22:16 - Ponte de cena
- 24:01 - Próximas etapas
Recursos
- Adopting best practices for persistent UI
- Tracking accessories in volumetric windows
- Petite Asteroids: Building a volumetric visionOS game
- Canyon Crosser: Building a volumetric hike-planning app
Vídeos relacionados
WWDC25
-
Buscar neste vídeo...
-
-
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 - Introdução
No visionOS 26, é possível usar as novas APIs para cenas, janelas, volumes e espaços imersivos, para criar apps mais dinâmicos e interativos. Os novos recursos incluem APIs de ciclo de vida, aprimoramentos volumétricos, "RemoteImmersiveSpace" para pré-visualização no Apple Vision Pro e APIs de ponte de cenas para apps do UIKit.
- 2:11 - Abertura e fixação
As novas APIs do visionOS 26 ajudam a gerenciar a abertura do app e a restauração de cenas, além de permitir a criação de experiências mais imersivas. As pessoas agora podem fixar janelas, volumes e widgets em espaços específicos, para que o conteúdo virtual se mantenha no ambiente físico. O sistema restaura automaticamente as janelas fixadas quando alguém retorna ao espaço associado. No entanto, você pode desativar a restauração para elementos transitórios, como as telas de boas-vindas ou uma interface dependente do contexto, usando o modificador "restorationBehavior(.disabled)". Você também pode personalizar o comportamento de abertura do app. Basta escolher dinamicamente a janela a ser exibida com base no estado do app com o modificador "defaultLaunchBehavior". Agora há suporte para janelas únicas, que não podem ser duplicadas, por meio da API Window para evitar a duplicação de interfaces importantes, como janelas de jogos ou chamadas de vídeo.
- 8:15 - Aprimoramentos para volumes
Os volumes também ganharam aprimoramentos importantes. Você pode utilizar a API "SurfaceSnappingInfo" para monitorar o momento em que as janelas e os volumes se encaixam em superfícies físicas, como paredes e mesas. Esse recurso oferece experiências mais imersivas, pois você pode ajustar a cena com base no estado do encaixe, como ocultar plataformas ou ajustar elementos de cena. Com a permissão do usuário, o ARKit pode fornecer ao app detalhes sobre a superfície ajustada. A atualização também expande os recursos de apresentação, permitindo que eles se originem de várias fontes dentro dos volumes, dos ornamentos e do RealityKit, com tratamentos visuais especiais para assegurar que permaneçam visíveis por trás do conteúdo 3D. Personalize o tratamento visual usando o modificador "presentationBreakthroughEffect". Além disso, use a nova API Clipping Margins para renderizar o conteúdo que não é interativo fora dos limites dos volumes das cenas, o que aprimorar os efeitos visuais, como cascatas ou nuvens, e assegura que o conteúdo principal permaneça focado e desobstruído. Leia sobre a variável de ambiente "windowClippingMargins" para saber se o sistema concedeu as margens.
- 15:58 - Espaço imersivo
Agora, você pode responder a um evento de recentralização do mundo, permitindo que as pessoas recalibrem a experiência do app em seu ambiente. Use o modificador de view "onWorldRecent" para observar esse evento e recalcular e armazenar as posições com base no novo sistema de coordenadas. O visionOS 26 também apresenta novas personalizações para os estilos de imersão. O estilo de imersão progressiva inclui proporção de retrato, o que permite experiências verticais e aumenta o conforto em conteúdo com movimentos intensos. O estilo de imersão mista agora permite que o conteúdo se integre perfeitamente aos ambientes do sistema, criando cenários ainda mais imersivos. Use o modificador de cena "immersiveEnvironmentBehavior" com o comportamento "coexist" para permitir a mesclagem. Você pode trazer seus apps para o macOS e pré-visualizar as cenas diretamente como espaços imersivos no Apple Vision Pro usando cenas "RemoteImmersiveSpace". Esse recurso permite iterações mais rápidas e facilita a colaboração. Use "CompositorLayer" para renderizar conteúdo com o Metal no Mac e exibi-lo no Apple Vision Pro. A apresentação do tipo de construtor "CompositorContent" permite que você use todo o poder do SwiftUI com "CompositorLayer", o que facilita a criação e o gerenciamento de experiências imersivas, tanto remotas quanto locais, o acesso às variáveis de ambiente, a adição de modificadores e o uso de variáveis de estado.
- 22:16 - Ponte de cena
A ponte de cenas no visionOS 26 permite adicionar volumes e espaços imersivos do SwiftUI a apps do UIKit. Ao estender o protocolo "UIHostingSceneDelegate", você pode criar cenas do SwiftUI e solicitá-las usando "UISceneSessionActivationRequest", o que permite que apps como o Safari implementem a Navegação Espacial e outros apps usem os novos recursos do visionOS.
- 24:01 - Próximas etapas
No app de exemplo, é possível criar cenas que são fixadas no local, encaixam-se nas superfícies e são abertas remotamente de um Mac. Analise seus próprios apps e garanta que eles aproveitem ao máximo esses novos recursos.