ophychius
ophychius

Reputation: 2653

AVCaptureVideoPreviewLayer, video orientation stuck

I have an iPhone camera app in which I use the AVCaptureVideoPreviewLayer. When someone takes a picture/stillImage this is shown in a new ViewController. The magic happens once this view controller is dismissed.

The whole app rotates properly, both viewcontroller; but for one exception. If I take a picture in one orientation, rotate the device in the new ViewController and then go back to the AVCaptureVideoPreviewLayer the whole layer rotates along just fine, except for the image, so suddenly the input is presented sideways through the previewLayer.

I have checked, and tried setting the frame for the PreviewLayer, but this all seems fine, the values I see when debugging are all correct. It is just the image that is displayed that is skewed. Rotating the device back and forth fixes this issue during use.

Has anyone seen this before, and does anyone have a clue how to fix this?

Upvotes: 2

Views: 2212

Answers (5)

bdev
bdev

Reputation: 2056

Since didRotateFromInterfaceOrientation: is deprecated in iOS 8, I change the video orientation of the connection in viewDidLayoutSubviews

switch ([UIApplication sharedApplication].statusBarOrientation) {
    case UIInterfaceOrientationPortrait:
        self.captureVideoPreviewLayer.connection.videoOrientation = AVCaptureVideoOrientationPortrait;
        break;
    case UIInterfaceOrientationPortraitUpsideDown:
        self.captureVideoPreviewLayer.connection.videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
        break;
    case UIInterfaceOrientationLandscapeLeft:
        self.captureVideoPreviewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
        break;
    case UIInterfaceOrientationLandscapeRight:
        self.captureVideoPreviewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
        break;
    default:
        break;
}

Upvotes: 1

Paul Wang
Paul Wang

Reputation: 1769

Since the interfaceOrientation is deprecated, the up to date swift 2.0 solution shall be:

let previewLayerConnection = self.previewLayer.connection
let orientation = AVCaptureVideoOrientation(rawValue: UIApplication.sharedApplication().statusBarOrientation.rawValue)
previewLayerConnection.videoOrientation = orientation!

Upvotes: 0

foundry
foundry

Reputation: 31745

You could change the previewLayer's connection's videoOrientation when the interface rotates

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    self.previewLayer.connection.videoOrientation = self.interfaceOrientation;
}

Upvotes: 2

Vinzzz
Vinzzz

Reputation: 11724

Maybe, instead of changing AVCaptureVideoPreviewLayer frame, you could try to put it in a container UIView, and set this container's frame. (I fixed a 'sizing' bug on ÀVCaptureVideoPreviewLayerthis way : sizing directly PreviewLayer had no effect, but sizing its containingUIView` worked).

Or, maybe you can force orientation in your viewController viewWillAppear (or viewDidAppear ?)

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // try and force current orientation
    UIApplication *application = [UIApplication sharedApplication];
    UIInterfaceOrientation currentOrientation = application.statusBarOrientation;
    [application setStatusBarOrientation:currentOrientation animated:animated];
}

Good luck !

Upvotes: 0

Luca Iaco
Luca Iaco

Reputation: 3467

I had a similar problem in the past. Once dismissed camera controller you could refresh view rotation with this:

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *topView = [window.subviews objectAtIndex:0];
[topView removeFromSuperview];
[window addSubview:topView];        

So, removing top most view on shown window and resetting it on window, it should refresh view rotation properly.

Hope it helps

Upvotes: 0

Related Questions