iPhone Xs-使用AVCaptureVideoPreviewLayer时,为什么UIView的顶部边框和安全区域的顶部边框之间会有很大的间距?

时间:2018-11-28 17:13:11

标签: ios swift avfoundation

我正在iphone Xs Max上开发自定义相机。我的布局如下。唯一的UIView的顶部,左侧,右侧和底部边框固定在安全区域。但是,我看到的是视频捕获输出的顶部边框和安全视图的顶部边框之间有一个巨大的黑色空间。黑色空间是什么,我该如何计算它的高度?

enter image description here

布局:

enter image description here

enter image description here

UIView约束: enter image description here

代码:

class NewCapturViewController: UIViewController, UIImagePickerControllerDelegate,AVCaptureVideoDataOutputSampleBufferDelegate  {

   var previewLayer = AVCaptureVideoPreviewLayer.init()
   var captureSession: AVCaptureSession!


   override func viewWillAppear(_ animated: Bool) {
       startAVCaptureSession()
   }


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
    self.camViewOutlet.layer.insertSublayer(self.previewLayer, at: 0)
    self.previewLayer.frame = self.camViewOutlet.frame
    self.previewFrame = previewLayer.frame


    print("previewLayer.frame: \(previewLayer.frame)")

}



}

2 个答案:

答案 0 :(得分:1)

您应该在viewDidLayoutSubviews中而不是在viewDidLoad中设置图层框架。请注意,视图的大小 change ,但是您添加的图层仍保持静态,因为它们不会随容器视图自动更新:

override func viewDidLayoutSubviews() {
   super.viewDidLayoutSubviews()

   self.previewLayer.frame = self.camViewOutlet.bounds
   self.previewFrame = previewLayer.frame
}

还要注意framebounds之间的区别。 camViewOutlet.frame是相对于其父视图(self.view)的,但是previewLayer放在camViewOutlet的内部,因此您必须使用camViewOutlet.bounds。基本上,因为camViewOutlet被放置在屏幕顶部(安全区域的高度)下方X个点,所以previewLayer也被放置在屏幕camViewOutlet顶部下方的X点。

您的代码中还有其他小问题。

请注意,viewWillAppear 必须调用super.viewWillAppear,并且它可以被多次调用,因此您永远不应在其中添加视图和图层。

您可能还应该在调用viewDidAppear之前不开始捕获。

答案 1 :(得分:0)

这是因为您已将Align Top设置为Safe Area。请记住,这款手机有一个缺口-因此安全区域会更低。

如果您将Storyboard中的电话更改为iPhone Xs(如问题中所述),则会发现您之间存在差距。您需要做的就是将最高约束设置为Superview,而不是Safe Area