0

I am working on a video recorder app with a custom camera UI (I don't want to use the native camera UI) and I keep getting an error with my code. To be more clear, I use the Storyboard for designing (I have a UIView for the Live Preview, a button to start recording and a "next" button for when the user has finished with recording (they need to be able to pause recording, thats's why it doesn't automatically go to the next view and why there's a next button).

This is a simple but very good working code that I've found on Stackoverflow from this question: How to Add Live Camera Preview to UIView.

    import UIKit
    import AVFoundation
    class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    //Camera Capture requiered properties
    var imagePickers:UIImagePickerController?

    @IBOutlet weak var customCameraView: UIView!

    override func viewDidLoad() {
        addCameraInView()
        super.viewDidLoad()
    }

    func addCameraInView(){

imagePickers = UIImagePickerController()
if UIImagePickerController.isCameraDeviceAvailable( UIImagePickerController.CameraDevice.rear) {
    imagePickers?.delegate = self
    imagePickers?.sourceType = UIImagePickerController.SourceType.camera

    //add as a childviewcontroller
    addChild(imagePickers!)

    // Add the child's View as a subview
    self.customCameraView.addSubview((imagePickers?.view)!)
    imagePickers?.view.frame = customCameraView.bounds
    imagePickers?.allowsEditing = false
    imagePickers?.showsCameraControls = false
    imagePickers?.view.autoresizingMask = [.flexibleWidth,  .flexibleHeight]
    }
}

@IBAction func cameraButtonPressed(_ sender: Any) {

     if UIImagePickerController.isSourceTypeAvailable(.camera){
        imagePickers?.takePicture()

     } else{

      //Camera not available.
    }
}
    }
    @IBAction func nextButtonPressed(_ sender: Any) {
    print("Button tapped")
    }

This works really well but when I click on the next button ( nextButtonPressed() ), the app crashes on this line of code:

    self.customCameraView.addSubview((imagePickers?.view)!)

The error I get is "Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value".

I thought that the Subview gave me that error and I've tried many ways to resolve this error but I haven't found a solution yet. This is what I've tried in nextButtonPressed() (note: I tried them all separately, not together, except for attempt 6).

    1
    self.customCameraView.remove((imagePickers?.view)!)

    2
    self.customCameraView.removeFromSuperview()

    3
    _ = customCameraView.layer.sublayers?.filter{ $0 is CAShapeLayer }.map{ $0.removeFromSuperlayer() }

    4 
    self.customCameraView.layer.sublayers?.popLast()

    5
    self.customCameraView.sendSubviewToBack((imagePickers?.view)!)

    6
    //self.customCameraView.sendSubviewToBack((imagePickers?.view)!)
    //        let storyboard = UIStoryboard (name: "Main", bundle: nil)
    //        let nextView = storyboard.instantiateViewController (withIdentifier: "VideoIsRecordedController")
    //        let navi = UINavigationController (rootViewController: nextView)
    //        present (navi, animated: true, completion: nil)

Before trying the 6th, the next button in the storyboard was connected to another view (an action segue to the next view).

I'd highly appreciate help!

  • 1
    I suggest putting a breakpoint on the bad line. It has 2 force unwraps and it should be easier to figure out the problem if you know which is wrong. When you hit the breakpoint, examine variables to see the value of `self.customCameraView` and of `imagePickers?.view`. – Phillip Mills Jul 21 '20 at 20:46
  • @PhillipMills thanks for the comment. I tried setting a breakpoint but I'm still stuck, I just keep on getting an error on that line. I thought viewDidDissapear would help but it keeps saying my code is wrong, could someone help me please? This is the code I used: `func removeCamereInView() { self.customCameraView.removeFromSuperview() }` `override func viewDidDisappear() { removeCamereInView() super.viewDidDisappear() }` – Coolmanneke Jul 22 '20 at 14:37
  • When you set the breakpoint, what did you see as values for the 2 variables I listed? – Phillip Mills Jul 22 '20 at 18:42
  • @PhillipMills `customCameraView = (UIView?) nil` and `imagePickers = (UIImagePickerController?) 0x00000001030a0000` Is this what you mean? Sorry, I'm not used to utilising breakpoints. – Coolmanneke Jul 23 '20 at 12:23
  • 1
    You got it! So, it's saying that your `customCameraView` outlet hasn't been initialized (and therefore calling a method on it is a crash). How are you creating this view controller? – Phillip Mills Jul 23 '20 at 12:36
  • @PhillipMills This is where I connected the UIView from the storyboard to my code: `@IBOutlet weak var customCameraView: UIView!`. I've tried letting 'weak' away but that didn't help too. Neither did changing customCameraView from UIView! to an optional UIView? . The code `@IBAction func nextButtonPressed(_ sender: Any) { print("Button tapped") }` which happens when the Next button gets pressed, does work however. It prints "Button tapped". – Coolmanneke Jul 23 '20 at 20:11
  • That's where you declared `customeCameraView` but did you actually make a connection inside the storyboard? Another thing to try is moving the `addCameraInView()` call into a `viewDidAppear` function instead of `viewDidLoad`. – Phillip Mills Jul 23 '20 at 20:41
  • And I asked how the controller was being created. Is it loaded automatically from the storyboard or do you create it in code? – Phillip Mills Jul 23 '20 at 20:45

0 Answers0