Reputation: 83
I have a custom camera view in a UIViewController that does not take up the full screen. Beneath it is a collection view that fills up with little thumbnails of images taken with "X's" on then to allow the user to delete them before uploading the kept ones to firebase.
This all works lovely on IPhone 7 sized screens. However on the plus size phones, the preview layer of the custom camera view does not fill the entire UIView that the camera is placed in.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let deviceSession = AVCaptureDeviceDiscoverySession(deviceTypes:
[.builtInDuoCamera, .builtInTelephotoCamera, .builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: .unspecified)
for device in (deviceSession?.devices)! {
if device.position == AVCaptureDevicePosition.back {
do {
let input = try AVCaptureDeviceInput(device: device)
if captureSession.canAddInput(input) {
captureSession.addInput(input)
if captureSession.canAddOutput(sessionOutput) {
captureSession.addOutput(sessionOutput)
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
previewLayer.connection.videoOrientation = .portrait
cameraView.layer.addSublayer(previewLayer)
cameraView.addSubview(takePhotoButton)
previewLayer.position = CGPoint(x: self.view.frame.width/2, y: self.cameraView.frame.height/2)
previewLayer.bounds = cameraView.frame
captureSession.startRunning()
}
}
} catch let avError {
print(avError)
}
}
}
}
Here is where I add the preview layer as a sublayer of the CameraView which is just a UIView added in the interface builder with constraints to allow space in the view for the collection view beneath it.
previewLayer.position = CGPoint(x: self.cameraView.frame.width/2, y: self.cameraView.frame.height/2)
previewLayer.bounds = cameraView.frame
I don't understand why the preview layer added as a sublayer would behave any differently on an Iphone7 than an Iphone 7 Plus?? Especially because you can see on the Iphone 7 Plus, the grey around the preview layer which suggests that the CameraView is being constrained correctly, why would it's frame.width be different.
It seems that on the Plus size phone, the preview layer remains the same size as it would on a regular size phone, while the CameraView itself conforms to the larger phone screen correctly.
here is the View in question in the interface builder
And this is what seems to happen on a plus size phone
Upvotes: 2
Views: 562
Reputation: 648
TL;DR: Set coordinates and frames of your views and layers in viewDidAppear()
method.
At the time viewWillAppear()
method executed, all view controller's subviews have frame
value that you've set in your Storyboard. What you need is to use updated cameraView.frame
value recalculated for the actual device size, to set your previewLayer.position
and previewLayer.bounds
properly. viewDidLayoutSubviews()
method exists just for this purpose — at the time it executed, all views have actual sizes recalculated for the particular device app is running on.
viewDidLayoutSubviews()
can be called multiple times though, which might lead to multiple instances of your views/layers created. There is another method in view controller's lifecycle which is called with autolayouted subviews just once — viewDidAppear()
.
So what you need is to move your previewLayer
related code from viewWillAppear()
to viewDidAppear()
.
Upvotes: 1