iOS 8 中不推荐使用“interfaceOrientation”,如何更改此方法 Objective C
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28787165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"interfaceOrientation" is deprecated in iOS 8, How to change this method Objective C
提问by GetMe4GetMe
I have downloaded a simpleCamera view from Cocoa Controls which use this method
我已经从使用这种方法的 Cocoa Controls 下载了一个 simpleCamera 视图
- (AVCaptureVideoOrientation)orientationForConnection
{
AVCaptureVideoOrientation videoOrientation = AVCaptureVideoOrientationPortrait;
switch (self.interfaceOrientation) {
case UIInterfaceOrientationLandscapeLeft:
videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
break;
case UIInterfaceOrientationLandscapeRight:
videoOrientation = AVCaptureVideoOrientationLandscapeRight;
break;
case UIInterfaceOrientationPortraitUpsideDown:
videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
break;
default:
videoOrientation = AVCaptureVideoOrientationPortrait;
break;
}
return videoOrientation;
}
the problem is "interfaceOrientation" deprecated in iOS 8 but i dont know what and how to replace this in Switch condition.
问题是在 iOS 8 中不推荐使用“interfaceOrientation”,但我不知道什么以及如何在 Switch 条件下替换它。
回答by cetcet
Getting the device orientation is not correct. For instance, the device might be in landscape mode, but a view controller that only supports portrait will remain in portrait.
获取设备方向不正确。例如,设备可能处于横向模式,但仅支持纵向的视图控制器将保持纵向。
Instead, use this:
相反,使用这个:
[[UIApplication sharedApplication] statusBarOrientation]
Another bonus is that it still uses the UIInterfaceOrientation enum, so very little of your code needs to change.
另一个好处是它仍然使用 UIInterfaceOrientation 枚举,所以你的代码很少需要改变。
回答by vmeyer
Since iOS8, Apple recommends to use TraitCollections (Size Classes) instead of interfaceOrientation.
从 iOS8 开始,Apple 建议使用 TraitCollections (Size Classes) 而不是 interfaceOrientation。
Moreover, since iOS 9 and the new iPad feature "Multitasking", there are some cases where the device orientation doesn't fit with the window proportions! (breaking your application UI)
此外,由于 iOS 9 和新 iPad 具有“多任务处理”功能,在某些情况下,设备方向与窗口比例不符!(破坏您的应用程序 UI)
So you should also be very careful when using Regular Size Classes because it will not necessary take up the whole iPad screen.
所以你在使用常规尺寸类时也应该非常小心,因为它不需要占据整个 iPad 屏幕。
Sometimes TraitCollections doesn't fill all your design needs. For those cases, Apple recommends to compare view's bounds :
有时 TraitCollections 并不能满足您的所有设计需求。对于这些情况,Apple 建议比较视图的边界:
if view.bounds.size.width > view.bounds.size.height {
// ...
}
I was quite surprised, but you can check on the WWDC 2015 video Getting Started with Multitasking on iPad in iOS 9at 21'15.
我很惊讶,但您可以在 21'15 观看WWDC 2015 视频在 iOS 9 上的 iPad 上的多任务处理入门。
Maybe you're really looking for the device orientation and not for the screen or window proportions. If you care about the device camera, you should not use TraitCollection, neither view bounds.
也许您真的在寻找设备方向而不是屏幕或窗口比例。如果您关心设备相机,则不应使用 TraitCollection,也不应使用视图边界。
回答by Abhishek Jain
Swift 4+ version
斯威夫特 4+ 版本
UIApplication.shared.statusBarOrientation
回答by Andrea
Using -orientation
property of UIDevice is not correct (even if it could work in most of cases) and could lead to some bugs, for instance UIDeviceOrientation
consider also the orientation of the device if it is face up or down, there is no pair in UIInterfaceOrientation
enum for those values.
Furthermore, if you lock your app in some particular orientation, UIDevice will give you the device orientation without taking that into account.
On the other side iOS8 has deprecated the interfaceOrientation
property on UIViewController
class.
There are 2 options available to detect the interface orientation:
使用-orientation
UIDevice 的属性是不正确的(即使它在大多数情况下都可以工作)并且可能会导致一些错误,例如UIDeviceOrientation
还要考虑设备的方向,如果它是面朝上或朝下,UIInterfaceOrientation
枚举中没有配对值。
此外,如果您将应用锁定在某个特定方向,UIDevice 将在不考虑设备方向的情况下为您提供设备方向。
另一方面,iOS8 已经弃用了classinterfaceOrientation
上的属性UIViewController
。
有 2 个选项可用于检测界面方向:
- Use the status bar orientation
- Use size classes, on iPhone if they are not overridden they could give you a way to understand the current interface orientation
- 使用状态栏方向
- 使用大小类,在 iPhone 上,如果它们没有被覆盖,它们可以让您了解当前的界面方向
What is still missing is a way to understand the direction of a change of interface orientation, that is very important during animations.
In the session of WWDC 2014 "View controller advancement in iOS8" the speaker provides a solution to that problem too, using the method that replaces -will/DidRotateToInterfaceOrientation
.
仍然缺少的是一种理解界面方向变化方向的方法,这在动画中非常重要。
在 WWDC 2014“iOS8 中的视图控制器改进”的会议中,演讲者也提供了该问题的解决方案,使用替换 -will/DidRotateToInterfaceOrientation
.
Here the proposed solution partially implemented:
这里提出的解决方案部分实施:
-(void) viewWillTransitionToSize:(CGSize)s withTransitionCoordinator:(UIVCTC)t {
orientation = [self orientationFromTransform: [t targetTransform]];
oldOrientation = [[UIApplication sharedApplication] statusBarOrientation];
[self myWillRotateToInterfaceOrientation:orientation duration: duration];
[t animateAlongsideTransition:^(id <UIVCTCContext>) {
[self myWillAnimateRotationToInterfaceOrientation:orientation
duration:duration];
}
completion: ^(id <UIVCTCContext>) {
[self myDidAnimateFromInterfaceOrientation:oldOrientation];
}];
}
回答by Bart van Kuik
When you use UIApplication.shared.statusBarOrientation
, Xcode 11 will show the warning 'statusBarOrientation' was deprecated in iOS 13.0: Use the interfaceOrientation property of the window scene instead.
使用时UIApplication.shared.statusBarOrientation
,Xcode 11 会显示警告'statusBarOrientation' was deprecated in iOS 13.0: Use the interfaceOrientation property of the window scene instead.
This answer is in Swift 5, and supports both iOS 13 and lower versions. It assumes the following:
这个答案在 Swift 5 中,并且支持 iOS 13 和更低版本。它假设如下:
- You will create only one scene, and never more than one
- You wish to contain your code to a specific view
- You have a view that has a member variable
previewLayer
of typeAVCaptureVideoPreviewLayer
- 您将只创建一个场景,并且永远不会超过一个
- 您希望将代码包含在特定视图中
- 您有一个具有成员变量
previewLayer
类型的视图AVCaptureVideoPreviewLayer
First, in your SceneDelegate.swift
, add the following lines:
首先,在您的 中SceneDelegate.swift
,添加以下几行:
static var lastCreatedScene: UIWindowScene?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let newScene = (scene as? UIWindowScene) else { return }
Self.lastCreatedScene = newScene
}
Then in your view, add the following function and call it in layoutSubviews()
:
然后在您的视图中,添加以下函数并调用它layoutSubviews()
:
func refreshOrientation() {
let videoOrientation: AVCaptureVideoOrientation
let statusBarOrientation: UIInterfaceOrientation
if #available(iOS 13, *) {
statusBarOrientation = SceneDelegate.lastCreatedScene?.interfaceOrientation ?? .portrait
} else {
statusBarOrientation = UIApplication.shared.statusBarOrientation
}
switch statusBarOrientation {
case .unknown:
videoOrientation = .portrait
case .portrait:
videoOrientation = .portrait
case .portraitUpsideDown:
videoOrientation = .portraitUpsideDown
case .landscapeLeft:
videoOrientation = .landscapeLeft
case .landscapeRight:
videoOrientation = .landscapeRight
@unknown default:
videoOrientation = .portrait
}
self.previewLayer.connection?.videoOrientation = videoOrientation
}