自从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
已经被弃用,苹果建议使用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,这似乎是一个已知的 bug)。即使这个 bug 被解决了,还有另一个问题:方向变化并不等同于大小变化。例如,如果一个视图使用 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]
可能不正确。
我不知道还有什么尝试的办法:(有任何想法吗?