“interfaceOrientation”在iOS 8中已被弃用,如何更改此方法Objective C

75

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

问题是"interfaceOrientation"在iOS 8中被弃用,但我不知道如何在Switch条件语句中替换它。


https://dev59.com/Y3RB5IYBdhLWcg3wZmhz#3897243 - beryllium
5个回答

147

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

取而代之,请使用以下方法:

[[UIApplication sharedApplication] statusBarOrientation]

另一个好处是它仍然使用UIInterfaceOrientation枚举,因此您的代码需要更改的部分非常少。


13
statusBarOrientation 在 iOS 9 中已被弃用 - https://developer.apple.com/documentation/uikit/uiapplication/1623026-statusbarorientation?language=objc - Pang

21
自iOS8以来,苹果建议使用TraitCollections(Size Classes)代替interfaceOrientation。
此外,自iOS9和新的iPad功能“多任务处理”以来,某些情况下设备方向可能与窗口比例不匹配!(破坏应用程序UI)
因此,在使用常规尺寸类时,您也应该非常小心,因为它不一定会占据整个iPad屏幕。
有时TraitCollections无法满足您的所有设计需求。对于这些情况,苹果建议比较视图的bounds:
if view.bounds.size.width > view.bounds.size.height {
    // ...
}

我非常惊讶,但您可以在WWDC 2015视频开始iOS 9中iPad上的多任务处理的21'15处进行检查。

也许您真正需要的是设备方向而不是屏幕或窗口比例。如果您关心设备相机,则不应使用TraitCollection或视图边界。


确实提到了。谢谢! - Ankish Jain
有没有推荐的方法可以知道设备是横向左侧或右侧?这真的很重要,尤其是对于iPhone X的刘海屏 :( - Pavel Alexeev
你可以使用[[UIDevice currentDevice] orientation]来检查实际设备方向,但是不应该将其用于iPhone X的适配。请使用新的iOS 11安全区域或旧的布局边距。 - vmeyer

3

Swift 4+ 版本

UIApplication.shared.statusBarOrientation

2
在iOS 13中,该方法会显示“'statusBarOrientation'已弃用:自iOS 13.0起首次弃用 - 请改用窗口场景的interfaceOrientation属性。”的消息。 - Peter Johnson

2
使用UIDevice的-orientation属性并不正确(即使大多数情况下可能可以工作),可能会导致一些错误,例如UIDeviceOrientation还会考虑设备是否面朝上或向下,而UIInterfaceOrientation枚举中没有那些值的对应项。此外,如果您将应用程序锁定在某个特定方向,则UIDevice将给出不考虑该方向的设备方向。
另一方面,iOS8已经将UIViewController类的interfaceOrientation属性弃用。检测界面方向有两个选项:
  • 使用状态栏方向
  • 使用大小类,在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
1
@Chandra 请在这里查看 http://blog.inferis.org/blog/2015/04/27/ios8-and-interfaceorientation/ - Andrea

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及更低版本。它假设以下内容:

  • 您将仅创建一个场景,而不会超过一个
  • 您希望将代码包含在特定视图中
  • 您有一个具有类型为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
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接