How can I detect and apply landscape orientation to AVCaptureVideoPreviewLayer in Swift?
Asked Answered
R

5

8

I'm basically after the answer to this question AVCaptureVideoPreviewLayer orientation - need landscape except in Swift.

I'm targeting iOS 8 and AVCaptureVideoPreviewLayer doesn't seem to have a setVideoOrientation function.

How should I be detecting that the orientation has changed, and rotating AVCaptureVideoPreviewLayer appropriately?

Rouvin answered 12/8, 2015 at 3:9 Comment(0)
L
24

Detect and apply it at viewWillLayoutSubviews or if you're using UIView subclass in layoutSubviews.

Here's how:

override func viewWillLayoutSubviews() {
                
    let orientation: UIDeviceOrientation = UIDevice.current.orientation

    previewLayer.connection?.videoOrientation = {
        switch (orientation) {
        case .portrait:
            return .portrait
        case .landscapeRight:
            return .landscapeLeft
        case .landscapeLeft:
            return .landscapeRight
        default:
            return .portrait
        }
    }()
}
Lumen answered 14/9, 2015 at 9:12 Comment(2)
thankyou sir... you saved my day... add this line before break will help previewLayer.frame = self.view.boundsMulderig
This needs to be updated for the latest Swift. Take note that the videoOrientation is flipped from the device orientation for landscape modes.Top
S
1

update for Swift 3

  override func viewWillLayoutSubviews() {

    let orientation: UIDeviceOrientation = UIDevice.current.orientation
    print(orientation)

    switch (orientation) {
    case .portrait:
        videoPreviewLayer?.connection.videoOrientation = .portrait
    case .landscapeRight:
        videoPreviewLayer?.connection.videoOrientation = .landscapeLeft
    case .landscapeLeft:
        videoPreviewLayer?.connection.videoOrientation = .landscapeRight
    case .portraitUpsideDown:
            videoPreviewLayer?.connection.videoOrientation = .portraitUpsideDown
    default:
        videoPreviewLayer?.connection.videoOrientation = .portraitUpsideDown
    }
}
Sulfide answered 8/11, 2017 at 11:27 Comment(0)
R
0

For me I need it to change orientation when I rotate iPad left or right, the solution that helped me is:

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    let orientation = UIDevice.current.orientation

    switch (orientation) {
    case .portrait:
        videoPreviewLayer?.connection.videoOrientation = .portrait
    case .landscapeLeft:
        videoPreviewLayer?.connection.videoOrientation = .landscapeRight
    case .landscapeRight:
        videoPreviewLayer?.connection.videoOrientation = .landscapeLeft
    default:
        videoPreviewLayer?.connection.videoOrientation = .portrait
    }
}
Rosol answered 24/7, 2018 at 11:55 Comment(0)
E
0

Xamarin Solution in ViewController;

public override void ViewWillLayoutSubviews()
    {
        base.ViewWillLayoutSubviews();

        var videoPreviewLayerConnection = PreviewView.VideoPreviewLayer.Connection;
        if (videoPreviewLayerConnection != null)
        {
            var deviceOrientation = UIDevice.CurrentDevice.Orientation;
            if (!deviceOrientation.IsPortrait() && !deviceOrientation.IsLandscape())
                return;

            var newVideoOrientation = VideoOrientationFor(deviceOrientation);
            var oldSize = View.Frame.Size;
            var oldVideoOrientation = videoPreviewLayerConnection.VideoOrientation;
            videoPreviewLayerConnection.VideoOrientation = newVideoOrientation;
        }
    }
Exedra answered 22/2, 2019 at 18:9 Comment(0)
S
0

another solution in Swift 4 it would be using Notification.

        NotificationCenter.default.addObserver(self,
                                           selector: #selector(detected),
                                           name: 

UIDevice.orientationDidChangeNotification, object: nil)

and in selector function you can check the orientation:

let orientation: UIDeviceOrientation = UIDevice.current.orientation
switch orientation {
    case .portrait:
         stuff()
    case .landscapeLeft:
         stuffOther()
    case .landscapeRight
         stuffOther()
    default:
         stuffOther()
}

Remember to remove observer when is not necessary.

Very IMPORTANT: your physical iPhone must NOT have lock on rotation (I've lost 2 hour for this because in this case, the method are not intercepted :) ).

Santoyo answered 3/9, 2019 at 10:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.