Creating a Custom Camera View

Accessing the built in Image Picker Controller is a quick and easy way to get image and video capture into your app. However, when you need style and functionality that goes beyond the stock Image Picker Controller you will need to create a Custom Camera View.

Live Camera Preview

Step 1: Set Up Views In Storyboard

Add the following view elements to the ViewController in Storyboard:

UIView This will serve as the "view finder" of your camera.

UIImageView This will hold the captured still image after you take a picture.

UIButton This button will "take a picture".

Step 2: Import AVFoundation

At the top of your ViewController file, import AVFoundation

Step 3: Create Outlets and Actions

Create Outlets for the UIView and UIImageView.

Name the UIView, previewView.

Name the UIImageView, captureImageView.

Create an Action for the UIButton.

Name the method, didTakePhoto.

Step 4: Define Instance Variables

Above the viewDidLoad method, where you create variables you want to be accessible anywhere in the ViewController file, create the following Instance Variables.

NOTE: If you plan to upload your photo to Parse, you will likely need to change your preset to AVCaptureSession.Preset.High or AVCaptureSession.Preset.medium to keep the size under the 10mb Parse max.

Step 7: Select Input Device

In this example, we will be using the rear camera. The front camera and microphone are additional input devices at your disposal. Printing debug comment incase the fetching the rear camera fails.
Still in viewDidAppear

guardletbackCamera=AVCaptureDevice.default(for:AVMediaType.video)else{print("Unable to access back camera!")return}

AVCaptureDevice*backCamera=[AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];if(!backCamera){NSLog(@"Unable to access back camera!");return;}

Step 8: Prepare the Input

We now need to make an AVCaptureDeviceInput. The AVCaptureDeviceInput will serve as the "middle man" to attach the input device, backCamera to the session.

We will make a new AVCaptureDeviceInput and attempt to associate it with our backCamera input device.

There is a chance that the input device might not be available, so we will set up a trycatch to handle any potential errors we might encounter. In Objective C, errors will be using the traditional NSError pattern.
Still in viewDidAppear

Step 12: Start the Session on the background thread

We need to call -startRunning on the session to start the live view. However -startRunning is a blocking method which means it will block the UI if it's running on the main thread. If the session takes a while to start, users would want the UI to be responsive and cancel out of the camera view.

Step 14: Taking the picture

Let's create an IBAction of the Take photo Button and capture a JPEG by calling our instance of AVCapturePhotoOutput or stillImageOut the method func capturePhoto(with:, delegate:) or -capturePhotoWithSettings:delegate:. This method requires us to provide it with a setting and a deleget to deliver the capturedPhoto to. This delegate will be this ViewController so we also need to conform to the protocol AVCapturePhotoCaptureDelegate

Step 15: Process the captured photo!

The AVCapturePhotoOutput will deliver the captured photo to the assigned delegate which is our current ViewController by a delegate method called photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?). The photo is delivered to us as an AVCapturePhoto which is easy to transform into Data/NSData and than into UIImage.