如何防止 iOS 11 上的旋转? [英] How to prevent rotation on iOS 11?

查看:13
本文介绍了如何防止 iOS 11 上的旋转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从 iOS 11.2 开始,我注意到不再调用 (BOOL)shouldAutorotate、(BOOL)shouldAutorotateToInterfaceOrientation、(UIInterfaceOrientationMask)supportedInterfaceOrientations 等.

As of iOS 11.2 I notice that (BOOL)shouldAutorotate, (BOOL)shouldAutorotateToInterfaceOrientation, (UIInterfaceOrientationMask)supportedInterfaceOrientations etc. are no longer called.

我现在如何防止旋转到某个方向?

How do I prevent rotation to a certain orientation now?

我可以在目标的部署级别关闭轮换,但我真正希望它为 iPhone X 关闭轮换只是.我有一个没有情节提要的旧应用程序,并且不要不想更改应用程序以在横向模式下尊重屏幕上的愚蠢缺口.

I can switch off rotation on the Deployment level of the target, but what I actually want it to switch off rotation just for the iPhone X. I have an older app without storyboards, and don't want to change the app to honour the silly notch in the screen in landscape mode.

横向在我的应用程序中很有用,因为在 iPhone 上,横向模式下您可以获得更宽的键盘,这很好.否则,我将删除所有 iPhone 型号的旋转..

Landscape IS useful in my App, as on iPhone you get a wider keyboard in landscape mode, which is nice. Else I'll just remove rotation for all iPhone models..

它在 UIViewController 的文档中:

从 iOS 8 开始,所有与旋转相关的方法都已弃用.相反,旋转被视为视图控制器视图大小的变化,因此报告使用..."

"As of iOS 8, all rotation-related methods are deprecated. Instead, rotations are treated as a change in the size of the view controller’s view and are therefore reported using..."

和:

你可以覆盖preferredInterfaceOrientationForPresentation.."

"You can override the preferredInterfaceOrientationForPresentation.."

但这也没有被调用.不在根视图控制器中,也不在其他视图控制器中.

but that is not called either. Not in the root view controller, nor in other viewcontrollers.

那么,我现在如何以编程方式防止旋转到某个方向?

So, how do I prevent rotation to a certain orientation now, programmatically?

推荐答案

文档中所述

视图控制器可以覆盖supportedInterfaceOrientations 方法来限制支持的方向列表.

A view controller can override the supportedInterfaceOrientations method to limit the list of supported orientations.

所以我们需要重写 shouldAutorotatesupportedInterfaceOrientation 来定位 view controllers.

So we need to override shouldAutorotate and supportedInterfaceOrientation to target view controllers.

通常,系统仅在窗口的根视图控制器或呈现为填满整个屏幕的视图控制器上调用此方法.

Typically, the system calls this method only on the root view controller of the window or a view controller presented to fill the entire screen.

如果您有非常简单的配置,例如您的目标 view controllerwindowrootViewController 或呈现覆盖整个屏幕,这将起作用.

This will work if you have very simple configuration like your target view controller is the rootViewController of window or being presented covering whole screen.

但是当你有像 target view controller 这样的其他配置被嵌入到像 UINavigationControllerUITabBarController 这样的其他容器视图控制器中时,那么现在应用程序的窗口只会向其 rootViewController(现在的 container view controller)询问 supportedInterfaceOrientation.

But when you have other configuration like your target view controller is embedded in some other container view controller like UINavigationController or UITabBarController, so now application's window will only ask its rootViewController (now container view controller) for supportedInterfaceOrientation.

现在进一步阅读文档,

子视图控制器使用其父视图控制器为它们提供的窗口部分,不再直接参与有关支持哪些旋转的决策.

child view controllers use the portion of the window provided for them by their parent view controller and no longer participate directly in decisions about what rotations are supported.

因此,这些容器视图控制器的默认实现可能不会向那里的孩子询问 supportedInterfaceOrientation 偏好.

So may be default implementation of these container view controllers not asking there children for there supportedInterfaceOrientation preference.

所以要让我们的目标 child view controller 指定 supportedIntefaceOrientation 我们需要告诉容器视图控制器这样做.

So to allow our target child view controller to specify there supportedIntefaceOrientation we need to tell there container view controller to do so.

如果是 UINavigationController

extension UINavigationController {
  open override var shouldAutorotate: Bool {
    return true
  }

  open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
      return topViewController?.supportedInterfaceOrientations ?? .allButUpsideDown
  }
}

万一还是UITabBarController

extension UITabBarController {
  open override var shouldAutorotate: Bool {
      return true
  }

  open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
      return selectedViewController?.supportedInterfaceOrientations ?? .allButUpsideDown
  }
}

编辑

要在视图控制器中实现正确的旋转行为,您应该将这些 ContainerViewController 子类化(UINavigationControllerUITabBarControllerUISplitViewController 等),然后覆盖这些属性,因为扩展这些 UIKit全局会导致 自定义现有类.

To implement proper rotation behaviour in your view controllers, you should subclass these ContainerViewController (UINavigationController, UITabBarController, UISplitViewController etc) and then override these properties, because extending these UIKit Classes globally will cause unexpected behavior as mentioned in Customizing Existing Classes.

如果一个类别中声明的方法的名称与原始类中的方法相同,或者同一类(甚至是超类)上的另一个类别中的方法,则行为未定义至哪个方法实现在运行时使用.如果您在自己的类中使用类别,这不太可能成为问题,但在使用类别向标准 Cocoa 或 Cocoa Touch 类添加方法时可能会导致问题.

If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime. This is less likely to be an issue if you’re using categories with your own classes, but can cause problems when using categories to add methods to standard Cocoa or Cocoa Touch classes.

这篇关于如何防止 iOS 11 上的旋转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆