// // InitialImmersiveView.swift // TestVideoLeakOneImmersiveView // import AVKit import OSLog import SwiftUI import RealityKit import RealityKitContent struct InitialImmersiveView: View { let logger = Logger(subsystem: SUBSYSTEM, category: "InitialImmersiveView") @Environment(\.scenePhase) var scenePhase @Environment(AppModel.self) var appModel private let rootEntity = Entity() var body: some View { RealityView { content, attachments in logger.info("\(#function) \(#line) `content, attachments in`") updateScene(content: content, attachments: attachments) } update: { content, attachments in logger.info("\(#function) \(#line) `update: { content, attachments in`") updateScene(content: content, attachments: attachments) } placeholder: { let _ = logger.info("\(#function) \(#line) `placeholder`") ProgressView() } attachments: { let _ = logger.info("\(#function) \(#line) `attachments`") Attachment(id: "OpenImmersiveView") { Button { // dismissCurrnt and open next immersive space logger.info("\(#function) \(#line) Button `OpenImmersiveView` pressed, appModel.immersiveSpaceID \(appModel.immersiveSpaceID)") appModel.immersiveSpaceID = "ImmersiveView" } label: { Text("Open ImmersiveView") } } } .onChange(of: scenePhase, { oldValue, newValue in logger.info("\(#function) \(#line) `onChange(of: scenePhase` scenePhase oldValue \(String(describing: oldValue)) scenePhase newValue \(String(describing: newValue))") switch newValue { case .active: logger.info("\(#function) \(#line) scenePhase newValue \(String(describing: newValue))") case .background: logger.info("\(#function) \(#line) scenePhase newValue \(String(describing: newValue))") unloadScenes() case .inactive: logger.info("\(#function) \(#line) scenePhase newValue \(String(describing: newValue))") @unknown default: logger.warning("\(#function) \(#line) scenePhase newValue \(String(describing: newValue))") } }) } func updateScene(content: RealityViewContent, attachments: RealityViewAttachments) { logger.info("\(#function) \(#line)") guard scenePhase == .active else { logger.info("\(#function) \(#line) escaping since app backgrounded") return } if rootEntity.children.isEmpty { Task{ await loadScenes(content: content, attachments: attachments) } } } func loadScenes(content: RealityViewContent, attachments: RealityViewAttachments) async { logger.info("\(#function) \(#line)") guard let closeImmersiveSpaceButton = attachments.entity(for: "OpenImmersiveView") else { logger.error("\(#function) \(#line) missing attachment") assertionFailure("missing attachment") return } closeImmersiveSpaceButton.position = [0.0, 0.1, -2.5] closeImmersiveSpaceButton.scale = scaleForAttachements rootEntity.addChild(closeImmersiveSpaceButton) content.add(rootEntity) } func unloadScenes() { logger.info("\(#function) \(#line)") rootEntity.children.removeAll() } } #Preview(immersionStyle: .mixed) { ImmersiveView() .environment(AppModel()) }