【发布时间】:2016-01-13 18:45:27
【问题描述】:
自 iOS 8.0 起,didRotateFromInterfaceOrientation 功能已被弃用,我现在不知道如何正确更改 AVCaptureVideoPreviewLayer 的方向。
根据"interfaceOrientation" is deprecated in iOS 8, How to change this method Objective C,我有以下工作代码来获取基于statusBarOrientation 的AVCaptureVideoOrientation:
- (AVCaptureVideoOrientation)getOrientation {
// Translate the orientation
switch ([[UIApplication sharedApplication] statusBarOrientation]) {
case UIInterfaceOrientationPortrait:
return AVCaptureVideoOrientationPortrait;
case UIInterfaceOrientationPortraitUpsideDown:
return AVCaptureVideoOrientationPortraitUpsideDown;
case UIInterfaceOrientationLandscapeLeft:
return AVCaptureVideoOrientationLandscapeLeft;
case UIInterfaceOrientationLandscapeRight:
return AVCaptureVideoOrientationLandscapeRight;
default:
return AVCaptureVideoOrientationPortrait;
}
}
当方向改变时我需要调用以下函数:
[self.videoPreviewLayer.connection setVideoOrientation:[self getOrientation]];
但我不知道把它放在哪里合适。
尝试 1
由于 didRotateFromInterfaceOrientation 已弃用且 Apple 建议使用 viewWillTransitionToSize:withTransitionCoordinator:,因此尝试一下似乎很自然:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[self.videoPreviewLayer.connection setVideoOrientation:[self getOrientation]];
}];
}
但是如果UIViewController 被呈现,这个函数不会被调用(似乎是一个基于"viewWillTransitionToSize:" not called in iOS 9 when the view controller is presented modally 的已知错误)。即使解决了这个错误,还有另一个问题:方向变化不等同于尺寸变化。例如,如果一个视图显示为UIModalPresentationFormSheet,如下所示,
SecondViewController *vc = [[SecondViewController alloc] init];
vc.view.backgroundColor = [UIColor greenColor];
vc.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:vc animated:true completion:nil];
iPad 横向和纵向模式下呈现的视图大小相同:
因此,我不能简单地使用viewWillTransitionToSize。
尝试 2
我注意到UIDeviceOrientationDidChangeNotification 没有被弃用。伟大的!我尝试注册一个通知:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Some other code to set up the preview layer
// ...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deviceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
- (void)viewWillDisappear:(BOOL)animated
{
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)deviceOrientationDidChange:(NSNotification *)notification {
[self.videoPreviewLayer.connection setVideoOrientation:[self getOrientation]];
}
这是几乎工作,它是如此封闭!问题是,当我收到设备方向更改通知时,可能会启动旋转视图的动画,也可能不会。或者换句话说,如果设备已经倒置旋转但动画仍处于未决状态,则返回值[[UIApplication sharedApplication] statusBarOrientation] 可能不正确。
我不知道还能尝试什么 :( 有什么想法吗?
【问题讨论】:
-
为什么不在“deviceOrientationDidChange”方法中使用UIDeviceOrientation,而不是状态栏方向?只需忽略 .FaceUp 和 .FaceDown 方向。
-
@almas,感谢您的评论。但问题是设备方向与界面方向并不完全相同。设备可能是上下颠倒的,但视图不支持 .FaceDown。如果我可以保证我当前的视图支持所有四个方向,那么,是的,我认为你的建议在这里是可以的!
-
好吧,您只需忽略您的应用不支持的所有方向,例如,您可以忽略 FaceUp、FaceDown 和 PortraitUpsideDown。试一试,我相信它会奏效的。
标签: ios objective-c ios8