我在UIViewController中有一个不占用全屏的自定义相机视图。在它下面是一个集合视图,用当前用“X”拍摄的图像的小缩略图填充,以允许用户在将保留的图像上传到firebase之前删除它们。
这一切在iPhone 7大小的屏幕上都很可爱。但是在加号手机上,自定义相机视图的预览图层不会填充放置相机的整个UIView。
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)
}
}
}
}
这里我将预览图层添加为CameraView的子图层,它只是在界面构建器中添加的UIView,其约束条件允许视图中的空间位于其下方。
previewLayer.position = CGPoint(x: self.cameraView.frame.width/2, y: self.cameraView.frame.height/2)
previewLayer.bounds = cameraView.frame
我不明白为什么作为子层添加的预览图层在Iphone7上的行为与Iphone 7 Plus相比有何不同? 特别是因为你可以在Iphone 7 Plus上看到预览层周围的灰色表明CameraView正在被正确约束,为什么它的frame.width会有所不同。
似乎在Plus尺寸的手机上,预览图层的尺寸与普通尺寸的手机尺寸相同,而CameraView本身也能正确适应更大的手机屏幕。
这是界面构建器中的有问题的视图
这似乎是在加大号手机上发生的事情
答案 0 :(得分:1)
TL; DR:使用viewDidAppear()
方法设置视图和图层的坐标和框架。
在执行viewWillAppear()
方法时,所有视图控制器的子视图都具有您在Storyboard中设置的frame
值。您需要的是使用针对实际设备大小重新计算的更新cameraView.frame
值来正确设置previewLayer.position
和previewLayer.bounds
。 viewDidLayoutSubviews()
方法仅用于此目的 - 在执行时,所有视图都会为正在运行的特定设备应用重新计算实际大小。
viewDidLayoutSubviews()
可以多次调用,这可能会导致创建视图/图层的多个实例。视图控制器的生命周期中还有另一种方法,只需使用自动浏览子视图调用一次 - viewDidAppear()
。
因此,您需要将previewLayer
相关代码从viewWillAppear()
移至viewDidAppear()
。