I have a AVCaptureVideoPreviewLayer
instance added to a view controller view hierarchy.
- (void) loadView {
...
self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:nil];
self.previewLayer.frame = self.view.bounds;
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer: _previewLayer];
// adding other UI elements
...
}
...
- (void) _setupPreviewLayerWithSession: (AVCaptureSession*) captureSession
{
self.previewLayer.session = self.captureManager.captureSession;
self.previewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
}
The layer frame is updated in -viewDidLayoutSubviews
method. View controller orientation is locked to UIInterfaceOrientationMaskLandscapeRight
.
The issue is as following:
I've tried updating the video layer orientation as following (with no results):
AVCaptureSessionDidStartRunningNotification
and UIApplicationDidBecomeActiveNotification
notifications-viewWillTransitionToSize:withTransitionCoordinator:
method is called-viewWillAppear:
The issue doesn't seem to be connected to video layer orientation itself, but more to view hierarchy layout.
UPDATE:
As suggested, I also tried updating the video layer orientation on device orientation change which didn't help.
I also noticed that the issue mostly happens after the application is launched and the screen is presented for the first time. On subsequent screen presentations during the same session, the reproduce rate for the issue is really low (something like 1/20).
Try this code:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
-(void)orientationChanged:(NSNotification *)notif {
[_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
if (_videoPreviewLayer.connection.supportsVideoOrientation) {
_videoPreviewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
}
- (AVCaptureVideoOrientation)interfaceOrientationToVideoOrientation:(UIInterfaceOrientation)orientation {
switch (orientation) {
case UIInterfaceOrientationPortrait:
return AVCaptureVideoOrientationPortrait;
case UIInterfaceOrientationPortraitUpsideDown:
return AVCaptureVideoOrientationPortraitUpsideDown;
case UIInterfaceOrientationLandscapeLeft:
return AVCaptureVideoOrientationLandscapeLeft;
case UIInterfaceOrientationLandscapeRight:
return AVCaptureVideoOrientationLandscapeRight;
default:
break;
}
// NSLog(@"Warning - Didn't recognise interface orientation (%d)",orientation);
return AVCaptureVideoOrientationPortrait;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With