iOS 8 中弃用了 didRotateFromInterfaceOrientation
didRotateFromInterfaceOrientation is deprecated in iOS 8
自 iOS 8.0 起,函数 didRotateFromInterfaceOrientation
已弃用,我现在不知道如何正确更改 AVCaptureVideoPreviewLayer 的方向。
根据 ,我有以下工作代码来获取基于 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]];
}
这几乎 正常工作,它是如此封闭!问题是,当我收到设备方向更改通知时,旋转视图的动画可能会开始,也可能不会。或者换句话说,如果设备已经上下旋转但动画仍在等待,则 return 值 [[UIApplication sharedApplication] statusBarOrientation]
可能不正确。
而且我不知道还能尝试什么:(有什么想法吗?
以下应该能够在 swift 2.1 中正确处理视频预览的方向:
override func viewWillAppear(animated: Bool) {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self,
selector: Selector("deviceOrientationDidChange:"),
name: UIDeviceOrientationDidChangeNotification,
object: nil)
}
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
super.viewDidDisappear(animated)
}
func deviceOrientationDidChange(sender: AnyObject) {
let deviceOrientation = UIDevice.currentDevice().orientation;
switch (deviceOrientation)
{
case .Portrait:
previewLayer.connection.videoOrientation = .Portrait
case .LandscapeLeft:
previewLayer.connection.videoOrientation = .LandscapeRight
case .LandscapeRight:
previewLayer.connection.videoOrientation = .LandscapeLeft
case .PortraitUpsideDown:
previewLayer.connection.videoOrientation = .PortraitUpsideDown
default:
break
}
}
自 iOS 8.0 起,函数 didRotateFromInterfaceOrientation
已弃用,我现在不知道如何正确更改 AVCaptureVideoPreviewLayer 的方向。
根据 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]];
}
这几乎 正常工作,它是如此封闭!问题是,当我收到设备方向更改通知时,旋转视图的动画可能会开始,也可能不会。或者换句话说,如果设备已经上下旋转但动画仍在等待,则 return 值 [[UIApplication sharedApplication] statusBarOrientation]
可能不正确。
而且我不知道还能尝试什么:(有什么想法吗?
以下应该能够在 swift 2.1 中正确处理视频预览的方向:
override func viewWillAppear(animated: Bool) {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self,
selector: Selector("deviceOrientationDidChange:"),
name: UIDeviceOrientationDidChangeNotification,
object: nil)
}
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
super.viewDidDisappear(animated)
}
func deviceOrientationDidChange(sender: AnyObject) {
let deviceOrientation = UIDevice.currentDevice().orientation;
switch (deviceOrientation)
{
case .Portrait:
previewLayer.connection.videoOrientation = .Portrait
case .LandscapeLeft:
previewLayer.connection.videoOrientation = .LandscapeRight
case .LandscapeRight:
previewLayer.connection.videoOrientation = .LandscapeLeft
case .PortraitUpsideDown:
previewLayer.connection.videoOrientation = .PortraitUpsideDown
default:
break
}
}