简体   繁体   中英

iOS camera view opening up at black intermittently

I have a viewcontroller which has a button that calls a second viewcontroller, which adds a video sublayer and calls the camera.

The code has been working fine until I tried adding other things like another button to the second viewcontroller, then, it would sometimes work and sometimes not work.

By "not work" I mean it would open up a black screen with nothing at all. Does not respond to anything.

I've deleted the buttons / code etc but it hasn't fixed anything.

It seems it would sometimes just work. Ie after it works I can add a button or change code and it would work and then it would show black screen again.

There are no build errors and trace and it basically is sitting there waiting for me to do something (like press the record button) but nothing is showing.

I've read that I should "bringsubviewtofront" but that doesn't seem to do anything.

Any suggestions?

Thanks in advance.

UPDATE: I think I found something related. I was trying to do a programmatically position a button on the screen using CGRect and part of that involved getting the text view's width and height.

I found that the code crashed with "expected to find optional value but found nil" message, ie I couldn't do anything like: textView.frame.width, textView.frame.height, textView.translatesAutoresizingMaskIntoConstraints = false etc.

At first I thought it was my code but after trying it on another VC using the same code, it suddenly started working again, ie I get values for textView.frame.width and textView.frame.height.

And my camera started showing preview!

So I reckon when the preview is black, then my buttons and text views have no values.

let captureSession = AVCaptureSession()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    captureSession.sessionPreset = AVCaptureSession.Preset.high

    // loop through all devices looking for cameras
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
    let devices = deviceDiscoverySession.devices

    for device in devices {
        if (device.hasMediaType(AVMediaType.video)) {
            if device.position == AVCaptureDevice.Position.back {
                backCamera = device
            } else if device.position == AVCaptureDevice.Position.front {
                frontCamera = device
            }
        }
    }
    currentDevice = frontCamera

    // look through all devices looking for microphone
    let audioDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInMicrophone], mediaType: AVMediaType.audio, position: AVCaptureDevice.Position.unspecified)
    let audioDevices = audioDiscoverySession.devices

    for audioDevice in audioDevices {
        if (audioDevice.hasMediaType(AVMediaType.audio)) {
            audioCapture = audioDevice
        }
    }

// set up input output
    do {
        // setup camera input
        let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!)
        captureSession.addInput(captureDeviceInput)
        // setup audio input
        let captureDeviceAudio = try AVCaptureDeviceInput(device: audioCapture!)
        captureSession.addInput(captureDeviceAudio)

        videoFileOutput = AVCaptureMovieFileOutput()
        captureSession.addOutput(videoFileOutput!)

    } catch {
        print(error)
    }

    cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill

    cameraPreviewLayer?.connection?.videoOrientation = currentVideoOrientation()

    cameraPreviewLayer?.frame = self.view.frame

    self.view.layer.insertSublayer(cameraPreviewLayer!, at: 0)

     captureSession.startRunning()

}

Check if you have provided the code to ask for the permission to your app to access the camera. If you have added the code but not allowed the app to access camera while it was asking permission, then got to settings > app name > camera and switch on the access. If not add this:

//Permission for Camera
AVCaptureDevice.requestAccess(for: AVMediaType.video) { response in
    if response {
        //access granted
    } else {
       //Take required action
    }
}

OK, I find out how to resolve it but I don't know why it's doing it, other than it's a bug in Xcode.

It seems the problem has nothing to do with the video sublayer and its code.

I have Text Views and buttons etc on this ViewController.

I found that if I change the size of a button or TextView, eg increase and decrease the size of a text view, then the problem goes away.

The problem comes back if you then change something, eg code or move buttons around etc. but if you go back to the Text View and change the size, then it'll work again.

That's the workaround but I don't know what triggers this problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM