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

查看:124
本文介绍了如何防止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.

Landscape在我的应用程序中很有用,就像在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天全站免登陆