ARKit Session Paused and Not Resuming

Viewed 8100

In my ARKit app I am presenting a modal window. When I close the modal and go back to the ARSCNView then I find out that the session is paused due to this code:

 override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // Pause the view's session
        sceneView.session.pause()
    } 

When I close the modal and go back to the ARKit camera view screen this code gets fired:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARWorldTrackingSessionConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
    }

But this code never resumes the session. The screen is completely frozen on the last image it read. Any ideas?

I update the viewDidAppear code to be the following. It is still stuck on the camera screen with image frozen.

  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)
        }


    }
5 Answers

Here's an answer working with Swift 4.2 and iOS 12.

To present UI defined in another view controller over your AR scene, create your view controller instance and set it's modalPresentationStyle property to .overCurrentContext:

EXAMPLE:

func showMaterialPicker(completion: (Texture?) -> Void) {

    // create an instance of your view controller, I have convenience functions
    // setup to do this via an extension on UIViewController
    guard let materialPicker = MaterialCategoriesViewController.instance(from: .product) else {
        print("Unable to instantiate MaterialCategoriesViewController, bailing")
        return
    }

    // set presentation style and transition style
    materialPicker.modalPresentationStyle = .overCurrentContext
    materialPicker.modalTransitionStyle = .crossDissolve

    // present the controller
    present(materialPicker, animated: true, completion: nil)
}

Bonus tip:

To make your overlay appear to slide up from the bottom like a drawer, set

materialPicker.modalTransitionStyle = .coverVertical

then constrain your views in your overlay view controller a comfortable height from the bottom and set the background color of the view controllers view to UIColor.clear.

If you want to darken the AR view while your overlay is displayed you can set the background color to a black color with an opacity/alpha value of approximately 0.75.

Something like this:

self.view.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.75)

or in the storyboard:

enter image description here

In the screenshot above I have a tableview pinned to the bottom and sides of the overlay view controllers view, and a height constraint of 300.

When done this way you can still see the AR view behind the overlay view controller and the scene continues to render.

Inside viewDidLoad: create a tap event.

arKitView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap(recognizer:))))

Inside viewWillAppear:

arView.session.run(configuration)

And then define the tap event. In which first tap will pause the session and second tap will resume the session and so on.

Related