ARKit会话暂停和不恢复

在我的ARKit应用程序中,我呈现一个模式窗口。 当我closures模式并返回到ARSCNView然后我发现会话暂停由于这个代码:

override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Pause the view's session sceneView.session.pause() } 

当我closures模式并返回到ARKit相机视图屏幕时,此代码被触发:

 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Create a session configuration let configuration = ARWorldTrackingSessionConfiguration() // Run the view's session sceneView.session.run(configuration) } 

但是这个代码永远不会恢复会话。 屏幕完全冻结在它读取的最后一个图像上。 有任何想法吗?

我更新viewDidAppear代码如下。 它仍然卡在相机屏幕冻结图像。

  override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Create a session configuration let configuration = ARWorldTrackingSessionConfiguration() sceneView.session.delegate = self if self.isPaused { sceneView.session.run(sceneView.session.configuration!) } else { // Run the view's session sceneView.session.run(configuration) } } 

不知道为什么你的会议不恢复,但是…这通常不是你想要的情况。

请注意,在自述文件中提供了Apple的ARKit示例代码(连接到ARKit上的WWDC17会话 ):

避免中断AR体验。 如果用户转换到应用中的另一个全屏用户界面,则AR视图在返回时可能不是预期的状态。

对于辅助视图控制器,使用popup式演示(甚至在iPhone上)可以在调整设置或进行模式select时使用户保持AR体验。 在这个例子中, SettingsViewControllerVirtualObjectSelectionViewController类使用popup窗口显示。

进一步详细一点:如果暂停会话,当用户离开不同的全屏视图控制器时,将不会跟踪世界。 这意味着,当您恢复时,放置在场景中的任何虚拟内容都不会位于您离开它的位置(相对于相机)。

我不知道iOS 11 GM种子或XCode 9 GM种子版本今天是否解决了这个问题,但是我可以像原始问题那样成功地恢复暂停的ARSCNview。

 sceneView.session.run(sceneView.session.configuration!) 

我得到你已经select了一个答案,这个答案是苹果推荐的,你可以重新启动AR Session。 不过,您不能取消暂停/恢复会话,因为设备停止跟踪,一旦您退出控制器并显示ARSceneView,并且将停止跟踪设备相对于放置在场景中的对象的位置。

无论如何,我已经设法重新启动会话,主要是通过销毁会话的所有方面,并在我的视图重新出现时重build它们,或通过button按下。

我会在这里发布一些示例代码。 它在Objective-C中,因为我的项目是用这个编写的,但是它可能会帮助那些有同样问题的未来的人。

 -(void)viewDidAppear:(BOOL)animated { [self setupScene]; [self setupSession]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self destroySession]; [self destroyScene]; } - (void)setupScene { // Setup the ARSCNViewDelegate - this gives us callbacks to handle new // geometry creation self.sceneView.delegate = self; // A dictionary of all the current planes being rendered in the scene self.planes = [NSMutableDictionary new]; // Contains a list of all the boxes rendered in the scene self.boxes = [NSMutableArray new]; // Show statistics such as fps and timing information self.sceneView.showsStatistics = YES; self.sceneView.autoenablesDefaultLighting = YES; SCNScene *scene = [SCNScene new]; [self.sceneView setScene:scene]; self.sceneView.scene.physicsWorld.contactDelegate = self; } - (void)setupSession { // Create a session configuration ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new]; //ARWorldTrackingSessionConfiguration *configuration = [ARWorldTrackingSessionConfiguration new]; This has been deprecated in favor of the previous line in XCode 9 beta 5. // Specify that we do want to track horizontal planes. Setting this will cause the ARSCNViewDelegate // methods to be called when scenes are detected //configuration.planeDetection = ARPlaneDetectionHorizontal; // Run the view's session [self.sceneView.session runWithConfiguration:configuration options:ARSessionRunOptionResetTracking]; } -(void)destroyScene { bottomPlane = nil; [self.sceneView setScene:nil]; [self.sceneView setDebugOptions:nil]; self.boxes = nil; self.planes = nil; self.sceneView.delegate = nil; } -(void)destroySession { [self.sceneView.session pause]; [self.sceneView setSession:nil]; } 

视图消失时使用这些销毁方法。 我也重新启动AR会话button按下,但它不是通过这些方法。 具体如下:

 -(void)resetPressed{ NSLog(@"Reset Pressed"); [_sceneView.session pause]; SCNScene *scene = [[SCNScene alloc] init]; [_sceneView setScene:scene]; [_sceneView.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode * _Nonnull child, BOOL * _Nonnull stop) { [child removeFromParentNode]; }]; ARWorldTrackingConfiguration *configuration = [[ARWorldTrackingSessionConfiguration ARWorldTrackingConfiguration] init]; [_sceneView.session runWithConfiguration:configuration options:ARSessionRunOptionResetTracking | ARSessionRunOptionRemoveExistingAnchors]; } 

希望能帮助到你。