iOS设备快速旋转180度会导致相机倒置 [英] Quick 180 rotation of iOS Device results in the camera viewing upside-down
问题描述
我已经实现了以下代码,根据 UIInterfaceOrientation
更改 AVCaptureVideoSession
的方向:
I've implemented the code below to change the orientation of an AVCaptureVideoSession
based upon the UIInterfaceOrientation
:
- (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 (%ld)",(long)orientation);
return AVCaptureVideoOrientationPortrait;
}
此代码几乎完美无缺。但是,出现的一个问题是,如果您快速将iOS设备旋转180度,相机将显示为颠倒。
This code works almost perfectly. However, one problem that occurs is that if you quickly rotate the iOS device 180 degrees, the camera will be shown upside down.
以下是轮换前相机视图的样子:
Here's what the camera view looks like before the rotation:
以下是轮换后的样子:
此外,这是我的 viewDidLayoutSubviews
的实现:
Additionally, here is my implementation of viewDidLayoutSubviews
:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
previewLayer.frame = self.view.bounds;
self.view.translatesAutoresizingMaskIntoConstraints = NO;
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:previewLayer];
if (previewLayer.connection.supportsVideoOrientation) {
previewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
}
有没有人知道为什么相机视图会这种180度旋转发生时会颠倒吗?
Does anyone have an idea of why the camera view would be upside down when this 180-degree rotation occurs?
推荐答案
我之前有同样的问题解决了我的问题。
I had the same issue before here what solved my issue.
我声明了一个全局变量:
I declared a global variable:
@interface YourViewController ()
{
...
UIDevice *iOSDevice;
}
..
@end
在实现
(.m文件)下,我在 -viewWillAppear
下声明了NSNotification观察者,如:
Under implementation
(.m file) i declared NSNotification observer under -viewWillAppear
like:
@implementation YourViewController
-(void)viewWillAppear:(BOOL)animated
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
}
-(void)viewWillDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
iOSDevice = notification.object;
previewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation];
//or
[self setAutoVideoConnectionOrientation:YES];
}
我做了一个函数,返回复制的当前方向设备如:
I made a function that returns the orientation of the copied current device like:
在我的 -interfaceOrientationToVideoOrientation
方法中获取战利品,它会转换 iOSDevice .orientation
进入 AVCaptureVideoOrientation
与你的相同......
Take a loot at my -interfaceOrientationToVideoOrientation
method, it converts the iOSDevice.orientation
into AVCaptureVideoOrientation
same with what you have there..
(在我的情况下,我需要以下功能,但看看它可能因某些原因对您有用)
(In my case i needed this functions below, but take a look at it might be useful to you for some reason)
- (AVCaptureVideoOrientation)interfaceOrientationToVideoOrientation
{
switch (iOSDevice.orientation) {
case UIInterfaceOrientationPortraitUpsideDown:
return AVCaptureVideoOrientationPortraitUpsideDown;
case UIInterfaceOrientationLandscapeLeft:
return AVCaptureVideoOrientationLandscapeLeft;
case UIInterfaceOrientationLandscapeRight:
return AVCaptureVideoOrientationLandscapeRight;
default:
case UIDeviceOrientationPortrait:
return AVCaptureVideoOrientationPortrait;
}
}
- (AVCaptureConnection *)setAutoVideoConnectionOrientation:(BOOL)status
{
AVCaptureConnection *videoConnection = nil;
//This is for me
//for (AVCaptureConnection *connection in stillImageOutput.connections) {
//This might be for you
for (AVCaptureConnection *connection in previewLayer.connection) {
for (AVCaptureInputPort *port in [connection inputPorts])
{
if ([[port mediaType] isEqual:AVMediaTypeVideo])
{
videoConnection = connection;
if (status == YES)
{
[videoConnection setVideoOrientation:[self interfaceOrientationToVideoOrientation]];
}
else
{
[videoConnection setVideoOrientation:AVCaptureVideoOrientationPortrait];
}
}
if (videoConnection)
{
break;
}
}
}
return videoConnection;
}
修改
默认方向:您需要检查当前方向。
For default orientation: You need to check the "current" orientation.
- (void)viewDidLoad
{
[super viewDidLoad];
// assuming you finish setting the `previewLayer`
..
// after all of that code, when the view is ready for displaying
// if you implemented this approach the best thing to do is:
// set this
iOSDevice = [UIDevice currentDevice];
// then call
previewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation];
// to update the `previewLayer.connection.videoOrientation ` for default orientation
}
注意:
使用 NSNotificationCenter
让设备的轮换先解决触发..
Using NSNotificationCenter
let the rotation of the device to be settled first before triggered..
希望这对你有帮助..
Hope this have help you..
这篇关于iOS设备快速旋转180度会导致相机倒置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!