imjaydeep
imjaydeep

Reputation: 978

When New View appears on Scene View App is Freezed

In one of my iOS App development project, whenever I am trying to push a view on ARSCNView. the app is freezing here below is my code. Please suggest an appropriate solution if you are aware of the same.

-> getting app froze when push view on sceneView controller

 let session = ARSession()
        var sessionConfig: ARSessionConfiguration = ARWorldTrackingSessionConfiguration()
        var use3DOFTracking = false {
            didSet {
                if use3DOFTracking {
                    sessionConfig = ARSessionConfiguration()
                }
                sessionConfig.isLightEstimationEnabled = true
                session.run(sessionConfig)
            }
        }    
    }

override func viewDidLoad() {
        super.viewDidLoad()
        self.setupScene()
        setupSession()
}

override func viewWillAppear(_ animated: Bool) {
        self.tabBarController?.tabBar.isHidden = false
        session.run(sessionConfig, options: [.resetTracking, .removeExistingAnchors])
    }

override func viewDidDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    session.pause()
}


 func setupScene() {
        sceneView.delegate = self
        sceneView.session = session
        sceneView.antialiasingMode = .multisampling4X
        sceneView.automaticallyUpdatesLighting = false

        sceneView.preferredFramesPerSecond = 60
        sceneView.contentScaleFactor = 1.3
        //sceneView.showsStatistics = true

        enableEnvironmentMapWithIntensity(25.0)

        if let camera = sceneView.pointOfView?.camera {
            camera.wantsHDR = true
            camera.wantsExposureAdaptation = true
            camera.exposureOffset = -1
            camera.minimumExposure = -1
        }
    }

    func setupSession() {
        if let worldSessionConfig = sessionConfig as? ARWorldTrackingSessionConfiguration {
            worldSessionConfig.planeDetection = .horizontal
            session.run(worldSessionConfig, options: [.resetTracking, .removeExistingAnchors])
        }
}

Upvotes: 11

Views: 1286

Answers (2)

Vasilii Muravev
Vasilii Muravev

Reputation: 3163

You shouldn't interrupt AR session for any reasons. Try to re-struct your design with popover screens.

There's a iOS 11 Beta bug, which freezes ARCamera, when ARSCNView disappears, so, if you really need to temporarily hide screen with AR:

  1. Remove ARSCNView from storyboard and remove IBOutlet from view controller;
  2. Create ARSCNView programmatically, when UIViewController appears;
  3. Remove ARSCNView, when UIViewController disappears.

There's a short example:

class ViewController: UIViewController, ARSCNViewDelegate {

    // Weak reference for scene view.
    weak var sceneView: ARSCNView!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // Create a new AR Scene View.
        let sceneView = ARSCNView(frame: view.bounds)
        sceneView.delegate = self
        sceneView.showsStatistics = true
        view.addSubview(sceneView)
        // Create a new scene.
        sceneView.scene = SCNScene(named: "art.scnassets/ship.scn")!
        // Running session.
        sceneView.session.run(ARWorldTrackingSessionConfiguration())
        // Saving weak reference.
        self.sceneView = sceneView
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // Removing current SceneView to avoid freezes.
        sceneView?.removeFromSuperview()
    }
}

Of course, you should check your frame for scene view and setup ARSCNView, ARSession and SCNScene as you need it.

Xcode Beta 5

Most of freezes was fixed in Beta 5. But sometimes it still freezes, like when you're using native sharing view controllers.

Upvotes: 2

Linkai Li
Linkai Li

Reputation: 1

It seems to me you should have an override function of viewDidAppear and initiate your setupSession() there.

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

    // Prevent the screen from being dimmed after a while.
    UIApplication.shared.isIdleTimerDisabled = true

    // Start the ARSession.
    setupSession()
}

Upvotes: -1

Related Questions