AVCaptureVideoPreviewLayer landscape orientation
First, the answer
- (void)viewWillLayoutSubviews {
_captureVideoPreviewLayer.frame = self.view.bounds;
if (_captureVideoPreviewLayer.connection.supportsVideoOrientation) {
_captureVideoPreviewLayer.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;
}
I've come across several SO posts on this matter, and couldn't find any simple explanation so I thought I'd share my own.
If you follow Apple's sample on the matter, you'll run into two potential problems when you rotate your iOS device to landscape
- Capture will appear rotated (as if you're holding the camera 90 degrees off)
- It won't span its set bounds entirely
The problem here is that 'CALayer' doesn't support autorotation hence, unlike a 'UIView' you'd add as a subview, it won't rotate when its parent 'UIView' rotates. Therefore, you have to manually update its frame every time the parent view's bounds changes (not parent view's frame since frame stays the same after rotation). This is achieved by overriding 'viewWillLayoutSubviews' in the container view controller.
Secondly, you should use 'videoOrientation' property to inform AVFoundation about the orientation so it does the preview properly.
Hope this helps.
AVCaptureVideoPreviewLayer orientation - need landscape
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.
Allow AVCaptureVideoPreviewLayer preview rotate with device
I fixed it - I just had to add this-
if UIDevice.current.orientation == .portrait {
previewLayer.connection?.videoOrientation = .portrait
} else if UIDevice.current.orientation == .portraitUpsideDown {
previewLayer.connection?.videoOrientation = .portraitUpsideDown
} else if UIDevice.current.orientation == .landscapeLeft {
previewLayer.connection?.videoOrientation = .landscapeRight
} else if UIDevice.current.orientation == .landscapeRight {
previewLayer.connection?.videoOrientation = .landscapeLeft
}
-which gets called when the device is rotated. I also call it on startup after I have initialized the AVCaptureVideoPreviewLayer
.
Related Topics
Swift - Coredata Migration - Set New Attribute Value According to Old Attribute Value
Get Advertisement Data for Ble in iOS
Are Cookies in Uiwebview Accepted
iOS Glsl. How to Create an Image Histogram Using a Glsl Shader
Calling Uiviewcontroller Method from App Delegate
Number of Days in the Current Month Using iOS
Proportional Height (Or Width) in Swiftui
Crashlytics iOS - Log Caught Exception
Swift Failed with Exit Code 1 While Compiling in Xcode - Possibly Related to Bridging-Headers
iOS 11 Large Navigation Bar Title Unexpected Velocity
Setting Maximum Number of Characters of 'Uitextview ' and 'Uitextfield '
What Do Horizontalaccuracy and Verticalaccuracy of a Cllocation Refer To
Perform Push Segue After an Unwind Segue
Can't Install Watchkit App on Apple Watch
How to Reference Uitableviewcontroller from a Uitableviewcell Class