AVCaptureVideoPreview图层横向框架

时间:2018-08-12 15:15:33

标签: ios swift

嗨,我遇到了AVCaptureVideoPreviewLayer的问题,当我将手机转向风景时,我丢失了一部分相机屏幕。

我要放一些照片。

当我处于纵向模式时

When i'm in portrait mode

当我切换到横向模式时 enter image description here

返回人像模式 enter image description here

代码:

func setupPreviewLayer(orientation: AVCaptureVideoOrientation) {
    cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
    cameraPreviewLayer?.connection?.videoOrientation = orientation
    cameraPreviewLayer?.frame.size = self.view.frame.size
    self.view.layer.insertSublayer(cameraPreviewLayer!, at: 0)
}

过渡卵磷脂:

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
    captureSession.stopRunning()
    if UIDevice.current.orientation.isLandscape {
        setupPreviewLayer(orientation: AVCaptureVideoOrientation.landscapeRight)
        setupRunningCaptureSession()
    }
    if UIDevice.current.orientation.isPortrait {
        setupPreviewLayer(orientation: AVCaptureVideoOrientation.portrait)
        setupRunningCaptureSession()
    }
}

3 个答案:

答案 0 :(得分:0)

在viewDidLoad

cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
//cameraPreviewLayer?.connection?.videoOrientation = orientation
cameraPreviewLayer?.frame.size = self.view.frame.size
self.view.layer.insertSublayer(cameraPreviewLayer!, at: 0)

然后将此代码添加到viewController

override func viewDidLayoutSubviews() {
        cameraPreviewLayer?.frame = view.frame
        if let cameraPreviewLayer = cameraPreviewLayer ,(cameraPreviewLayer.connection?.isVideoOrientationSupported)! {
            cameraPreviewLayer.connection?.videoOrientation = UIApplication.shared.statusBarOrientation.videoOrientation ?? .portrait
        }
    }

答案 1 :(得分:0)

我遇到了同样的问题,发现willTransition中缺少的是: cameraPreviewLayer?.frame = view.frame

此外,我认为每次旋转都创建一个额外的图层是没有用的。 这是我正在使用的代码下方

在ViewDidLoad()

  videoPreviewLayer = AVCaptureVideoPreviewLayer(session: camera.session)

  videoPreviewLayer!.frame = view.layer.bounds
  videoPreviewLayer!.videoGravity = AVLayerVideoGravity.resizeAspectFill


  let statusBarOrientation = UIApplication.shared.statusBarOrientation
  videoPreviewLayer!.connection?.videoOrientation = statusBarOrientation.videoOrientation!

  view.layer.addSublayer(videoPreviewLayer!)

在willTransition中

DispatchQueue.main.async {

        self.videoPreviewLayer!.frame = self.view.frame

        let statusBarOrientation = UIApplication.shared.statusBarOrientation
        self.videoPreviewLayer!.connection?.videoOrientation = statusBarOrientation.videoOrientation ?? .portrait

}

根据我在iOS 12.1上的测试,DispatchQueue是必需的。 希望能有所帮助。

答案 2 :(得分:0)

调用willTransition(to:with:)时,视图的框架尚未更新。您应该改用traitCollectionDidChange(_:)

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    captureSession.stopRunning()
    if UIDevice.current.orientation.isLandscape {
        setupPreviewLayer(orientation: AVCaptureVideoOrientation.landscapeRight)
        setupRunningCaptureSession()
    }
    if UIDevice.current.orientation.isPortrait {
        setupPreviewLayer(orientation: AVCaptureVideoOrientation.portrait)
        setupRunningCaptureSession()
    }
}