I am trying to build a custom camera using a single view application with the new iPhone Xs Max. With reference to the screenshot below, it can be seen that the video output displayed in AVCaptureVideoPreviewLayer occupies less than the safe area of the screen on the iPhone x. How do I calculate the space that has not been occupied?
How do I know that the AVCaptureVideoPreviewLayer occupies less than the safe area? Well, the top border of the top 'Button' is anchored to the top border of the safe area. The bottom button is similarly anchored to the bottom of the bottom safe area. Yet there is huge overlap!
Problem:
The layout of single view application: Button top constraint
Bottom white button bottom constraint:
All other layout constraints:
SWIFT:
class ViewController: UIViewController, UIImagePickerControllerDelegate, AVCaptureVideoDataOutputSampleBufferDelegate {
var previewLayer = AVCaptureVideoPreviewLayer.init()
var captureSession: AVCaptureSession!
var previewFrame = CGRect.init()
var safeAreaFrame: CGRect = CGRect.init()
override func viewDidLoad() {
super.viewDidLoad()
let screenSize = UIScreen.main.bounds
// This is (0.0, 0.0, 414.0, 896.0)
startAVCaptureSession()
}
override func viewDidLayoutSubviews() {
print("viewDidLayoutSubviews ...")
let sAreaFrame = UIApplication.shared.windows[0].safeAreaLayoutGuide.layoutFrame
self.safeAreaFrame = sAreaFrame
// self.safeAreaFrame - This is (0.0, 44.0, 414.0, 818.0)
self.previewLayer.frame = view.bounds // // I have tried self.previewLayer.frame = self.safeAreaFrame
self.previewFrame = previewLayer.frame
}
func startAVCaptureSession() {
print("START CAPTURE SESSION!!")
// Setting Up a Capture Session
self.captureSession = AVCaptureSession()
captureSession.beginConfiguration()
// Configure input
let videoDevice = AVCaptureDevice.default(for: .video)
guard
let videoDeviceInput = try? AVCaptureDeviceInput.init(device: videoDevice!) as AVCaptureInput,
self.captureSession.canAddInput(videoDeviceInput)else {return}
self.captureSession.addInput(videoDeviceInput)
// Capture video output
let videoOutput = AVCaptureVideoDataOutput.init()
guard self.captureSession.canAddOutput(videoOutput) else {return}
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.init(label: "videoQueue"))
self.captureSession.addOutput(videoOutput)
// start
self.captureSession.commitConfiguration()
self.captureSession.startRunning()
// Display camera preview
self.previewLayer = AVCaptureVideoPreviewLayer.init(session: self.captureSession)
// Use 'insertSublayer' to enable button to be viewable
view.layer.insertSublayer(self.previewLayer, at: 0)
}
}
PROJCT LINK: https://github.com/babylon123/RectangleCapture