iOS 8中不推荐使用“ interfaceOrientation”,如何更改此方法


75

我已经从可可控件下载了一个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;
}

问题是iOS 8中不推荐使用“ interfaceOrientation”,但我不知道该如何以及如何在Switch条件下替换它。


Answers:


145

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

而是使用以下命令:

[[UIApplication sharedApplication] statusBarOrientation]

另一个好处是它仍然使用UIInterfaceOrientation枚举,因此几乎不需要更改任何代码。


9
statusBarOrientation弃用在IOS 9 - developer.apple.com/documentation/uikit/uiapplication/...

21

从iOS8开始,Apple建议使用TraitCollections(大小类)而不是interfaceOrientation。

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

因此,在使用常规尺寸类别时,您也应该非常小心,因为它不必占用整个iPad屏幕。

有时TraitCollections无法满足您的所有设计需求。对于这些情况,Apple建议比较视图的边界:

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

我很惊讶,但是您可以在21'15观看WWDC 2015视频(iPad 9上的iPad上的多任务入门)

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


确实提到了。谢谢!!
Ankish Jain

有没有建议的方法来知道设备是横向还是横向?iPhone X的缺口真的很重要:(
Pavel Alexeev

好吧,[[UIDevice currentDevice] orientation]如果您想检查真实的设备方向,可以使用它,但不要将其用于iPhone X适配。请使用新的iOS 11安全区域或旧的布局边距。
vmeyer


2

使用-orientationUIDevice的属性是不正确的(即使在大多数情况下也可以使用),并且可能导致某些错误,例如UIDeviceOrientation,如果设备面朝上或朝下,则还要考虑设备的方向,对于这些设备,UIInterfaceOrientation枚举中没有对价值观。
此外,如果您将应用锁定为某个特定方向,则UIDevice会为您提供设备方向,而无需考虑这一点。
另一方面,iOS8已弃用该类的interfaceOrientation属性UIViewController
有2个选项可用于检测界面方向:

  • 使用状态栏方向
  • 在iPhone上使用尺寸类别,如果它们没有被覆盖,它们可以为您提供一种了解当前界面方向的方式

仍然缺少的是一种了解界面方向变化方向的方法,这在动画制作过程中非常重要。
在WWDC 2014“ iOS8中的视图控制器改进”会议上,演讲者也使用替换方法为该问题提供了解决方案 -will/DidRotateToInterfaceOrientation

此处提出的解决方案部分实现:

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

orientationFromTransform:方法如何从变换中得出方向?
Chandra


0

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

这个答案在Swift 5中,并且支持iOS 13和更低版本。它假定以下内容:

  • 您将只创建一个场景,最多只能创建一个
  • 您希望将代码包含在特定视图中
  • 您有一个具有成员变量previewLayer类型的视图AVCaptureVideoPreviewLayer

首先,在中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
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.