Search code examples
iosswiftcamerasegueavcapturesession

Segue to controller takes 5-10 seconds to display


I am using swift 4 and have an app where people can open their phone camera through my app. I have a ViewController called CameraController which has the default UIView and I have a view on top of that called CameraView which displays the users camera and other buttons on top of that.

When I clicked one of those buttons it takes me to another view controller via a segue (PlacesController). When I dismiss the PlacesController I go back to the CameraController however the subview now takes about 8 or 10 seconds to display again.

Is there someway that I can go to another Controller while maintaining my current subview?

Again the issue is that when I go to my segue controller PlaceController and then go back to my CameraController it takes about 8 or 10 seconds before the camera and sublayer become visible. Specifically this code below and I was wondering if I could keep my sublayer still running since waiting 10 seconds for it to show is too much.

self.CameraView.layer.insertSublayer(previewLayer!, at: 0)

This is my code:

class CameraController: UIViewController {
    @IBOutlet weak var CameraView: UIView!
     var previewLayer: AVCaptureVideoPreviewLayer?
     let captureSession = AVCaptureSession()


  override func viewDidLoad() {
        super.viewDidLoad()


    }
 override func viewDidAppear(_ animated: Bool) {
           DispatchQueue.main.async {
             self.beginSession()
        }

    func beginSession() {
   // gets the camera showing and displays buttons on top of it
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        self.CameraView.layer.insertSublayer(previewLayer!, at: 0)
        previewLayer?.frame = self.CameraView.layer.bounds

        previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        captureSession.startRunning()
        stillImageOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecType.jpeg]
        if captureSession.canAddOutput(stillImageOutput) {
            captureSession.addOutput(stillImageOutput)
        }
    }


  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "PlacesController" {
            let PlaceAreaSearchC: ColorC = segue.destination as! PlacesController
            PlaceAreaSearchC.delegate = self
        }
    }

 // PlacesController
class PlacesController: UIViewController {
    @IBAction func backAction(_ sender: Any) {
   // This is how I go back to my view CameraController
         dismiss(animated: true, completion: nil)
    }
 }

Solution

  • The AVCaptureSession startRunning call is blocking your main thread thus the delay.

    As it says in startRunning()’s Apple Doc:

    The startRunning() method is a blocking call which can take some time, therefore you should perform session setup on a serial queue so that the main queue isn't blocked (which keeps the UI responsive).