iOS设备快速旋转180°会导致相机颠倒
我已经实现了下面的代码来改变基于AVCaptureVideoSession
的方向:
- (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度,相机将显示颠倒。
以下是相机视图在旋转之前的样子:
轮换之后的样子如下所示:
另外,这里是我的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度的旋转发生时,为什么相机视图会颠倒?
在这之前我有同样的问题解决了我的问题。
我宣布了一个全局variables:
@interface YourViewController () { ... UIDevice *iOSDevice; } .. @end
在implementation
(.m文件)我宣布NSNotification观察员在-viewWillAppear
像:
@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]; }
我做了一个函数,返回复制的当前设备的方向,如:
在我的iOSDevice.orientation
方法采取掠夺,它将iOSDevice.orientation
转换为AVCaptureVideoOrientation
与您在那里相同。
(在我的情况下,我需要下面的这个function,但看看它可能是有用的,你出于某种原因)
- (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; }
编辑
对于默认方向:您需要检查“当前”方向。
- (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
让设备的旋转在触发之前先被解决。
希望这有助于你..
我相信这是因为viewDidLayoutSubviews
在视图从纵向变为UpsideDown时不会被调用。 当你很快旋转时,它会从一个直线到另一个直线。 如果缓慢旋转,则会通过横向方向,因此将调用viewDidLayoutSubviews
,随后调用您的方法。
我build议你使用方向改变时调用的方法之一。 我知道苹果build议使用它们的次数越来越less,因为他们希望视图在大小改变时发生改变,但是有些情况下,比如当你真的需要知道改变方向时。
例如,您可以注册以接收此通知: UIApplicationDidChangeStatusBarOrientationNotification