AVCaptureVideoPreviewLayer orientation - need landscape

Swift 5.5, Xcode 13.2

private func updatePreviewLayer(layer: AVCaptureConnection, orientation: AVCaptureVideoOrientation) {
    layer.videoOrientation = orientation
    self.previewLayer?.frame = view.bounds
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    if let connection = self.previewLayer?.connection {
        let currentDevice = UIDevice.current
        let orientation: UIDeviceOrientation = currentDevice.orientation
        let previewLayerConnection: AVCaptureConnection = connection
        
        if previewLayerConnection.isVideoOrientationSupported {
            switch orientation {
            case .portrait: self.updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)
            case .landscapeRight: self.updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeLeft)
            case .landscapeLeft: self.updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeRight)
            case .portraitUpsideDown: self.updatePreviewLayer(layer: previewLayerConnection, orientation: .portraitUpsideDown)
            default: self.updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)
            }
        }
    }
}

Swift 2.2, Xcode 7.3

private func updatePreviewLayer(layer: AVCaptureConnection, orientation: AVCaptureVideoOrientation) {
    
    layer.videoOrientation = orientation

    previewLayer.frame = self.view.bounds

}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    if let connection =  self.previewLayer?.connection  {
        
        let currentDevice: UIDevice = UIDevice.currentDevice()
        
        let orientation: UIDeviceOrientation = currentDevice.orientation
        
        let previewLayerConnection : AVCaptureConnection = connection
        
        if (previewLayerConnection.supportsVideoOrientation) {
            
            switch (orientation) {
            case .Portrait: updatePreviewLayer(previewLayerConnection, orientation: .Portrait)
                                
            case .LandscapeRight: updatePreviewLayer(previewLayerConnection, orientation: .LandscapeLeft)
                                
            case .LandscapeLeft: updatePreviewLayer(previewLayerConnection, orientation: .LandscapeRight)
                                
            case .PortraitUpsideDown: updatePreviewLayer(previewLayerConnection, orientation: .PortraitUpsideDown)
                                
            default: updatePreviewLayer(previewLayerConnection, orientation: .Portrait)
            
            }
        }
    }
}

The default camera orientation is Landscape Left (home button one the left). You need to do two things here:

1- Change the previewLayer frame to:

self.previewLayer.frame=self.view.bounds;

You need to set the preview layer frame to the bounds of the screen so that the frame of the preview layer changes when the screen rotates (you cannot use frame of the root view because that does not change with rotation but the bounds of the root view do). In your example, you are setting the previewlayer frame to a previewView property which I do not see.

2- You need to rotate the preview layer connection with the rotation of the device. Add this code in viewDidAppear:

-(void) viewDidAppear:(BOOL)animated
{
  [super viewDidAppear:YES];

  //Get Preview Layer connection
  AVCaptureConnection *previewLayerConnection=self.previewLayer.connection;

  if ([previewLayerConnection isVideoOrientationSupported])
    [previewLayerConnection setVideoOrientation:[[UIApplication sharedApplication] statusBarOrientation]]; 
}

Hope this solves it.

Full Disclosure: This is a simplified version since you do not care if Landscape right or Landscape left.