在 iOS8系统中,“界面导向”是不被推崇的,如何改变这种方法目标 C

我已经从 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;
}

问题是“界面定位”在 iOS8中已经废弃了,但是我不知道在 Switch 条件下如何替换它。

40256 次浏览

获取设备方向不正确。例如,设备可能处于横向模式,但只支持纵向的视图控制器将保持纵向。

相反,使用以下方法:

[[UIApplication sharedApplication] statusBarOrientation]

另一个好处是它仍然使用 UIInterfaceOrientenum,所以您的代码很少需要更改。

使用 UIDdevice 的 -orientation属性是不正确的(即使它在大多数情况下可以工作) ,并可能导致一些错误,例如 UIDeviceOrientation也考虑设备的方向,如果它是正面朝上或向下,在 UIInterfaceOrientation枚举没有对这些值。
此外,如果你锁定你的应用程序在某个特定的方向,UIDevice 会给你的设备方向没有考虑到这一点。
另一方面,iOS8已经废弃了 UIViewController类上的 interfaceOrientation属性。
有两个选项可用于检测界面方向:

  • 使用状态栏方向
  • 在 iPhone 上使用 size 类,如果它们没有被覆盖,它们可以让你理解当前界面的方向

仍然缺少的是理解界面方向变化的方向,这在动画中非常重要。在 WWDC 2014“ iOS8视图控制器的进步”的会议上,演讲者也提供了一个解决这个问题的方案,使用的方法取代了 -will/DidRotateToInterfaceOrientation。< br >

在这方面,拟议的解决办法得到部分实施:

-(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];
}];
}

自 iOS8以来,苹果公司推荐使用 TraitCollectionsSize 类来代替界面定位。

此外,由于 iOS9和新的 iPad 功能“多任务”,有些情况下,设备的方向不符合窗口比例!(破坏应用程序用户界面)

所以你在使用普通尺寸类的时候也应该非常小心,因为它不需要占据整个 iPad 屏幕。

有时 TraitCollective 并不能满足你所有的设计需求,对于这些情况,苹果建议比较一下 view 的界限:

if view.bounds.size.width > view.bounds.size.height {
// ...
}

我很惊讶,但是你可以在21分15秒的时候查看 WWDC 2015年的视频 在 iOS9中开始在 iPad 上进行多任务处理

也许你真的在寻找设备的方向,而不是屏幕或窗口的比例。如果您关心设备摄像头,则不应使用 TraitCollection,也不应使用视图边界。

Swift 4 + 版本

UIApplication.shared.statusBarOrientation

使用 UIApplication.shared.statusBarOrientation时,Xcode 11将显示警告 'statusBarOrientation' was deprecated in iOS 13.0: Use the interfaceOrientation property of the window scene instead.

这个问题的答案在 Swift 5中,它支持 iOS13和更低的版本:

  • 你只能创建一个场景,而且不能超过一个
  • 您希望将代码包含在特定视图中
  • 您有一个具有类型为 AVCaptureVideoPreviewLayer的成员变量 previewLayer的视图

首先,在 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
}

然后在视图中,添加以下函数并在 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
}