iOS屏幕旋转技术点及解决方案总结

Posted super_man_风清扬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS屏幕旋转技术点及解决方案总结相关的知识,希望对你有一定的参考价值。

1.屏幕旋转相关枚举

关于屏幕旋转枚举一共有3种:

UIInterfaceOrientation,    UIInterfaceOrientationMask,   UIDeviceOrientation
1.1 UIInterfaceOrientation 和 UIDeviceOrientation

UIDeviceOrientation是设备当前所处的方向, 它有7个值


UIInterfaceOrientation 是屏幕当前所处的方向,它有5个值

UIInterfaceOrientation和UIDeviceOrientation相比,有两点需要注意:

1.UIInterfaceOrientaion与UIDeviceOrientation是相互对应的,但UIInterfaceOrientaion比UIDeviceOrientation多了两个枚举:

UIDeviceOrientationFaceUp(屏幕朝上平躺)

UIDeviceOrientationFaceDown(屏幕朝下平躺)

2.在处于竖屏和上下翻转的状态时,两个枚举值方向是相同的,但当处于横屏时,两个枚举值正好相反:

UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,

UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
1.2 UIInterfaceOrientationMask

苹果提供了一个更加方便的位移枚举。在做横竖屏适配时,使用的较多的是这个枚举


2.屏幕旋转权限开启方式

开启屏幕旋转权限的方式有两种:

1.在TARGETS→General中进行勾选:

勾选后,在info.plist文件中会自动生成对应支持的屏幕方向配置项。

注意:由于在这里配置会对项目启动时的lanuch界面产生影响,一般我们不会对lanuch进行横竖屏适配,所以不建议使用该种方式进行配置。

2.在AppDelegate中进行设置

在Deplyment Info中,只勾选Portrait.然后在AppDelegate如下方法中配置支持的屏幕方向:

3.屏幕旋转相关属性及方法

3.1 UIViewController

@property(nonatomic, readonly) BOOL shouldAutorotate NS_AVAILABLE_ios(6_0) __TVOS_PROHIBITED;

-- 页面是否支持自动旋转

@property(nonatomic, readonly) UIInterfaceOrientationMask supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;

-- 页面支持的选择方向

@property(nonatomic, readonly) UIInterfaceOrientation preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;

-- 页面初始时默认展示的屏幕方向

注意:这三个属性都是只读的,在swift中若要重写其值,需引入一个自定义属性,然后重写其get, set方法:

3.2 获取设备方向(只读)

[UIDevice currentDevice].orientation

setOrientation是私有属性,若想手动改变屏幕方向,不能直接调用setOrientation方法,可以使用NSInvocation对象给[UIDevice currentDevice]发setOrientation消息,强制改变屏幕方向。

3.3 设备旋转监听

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onDeviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];

在通知回调中,通过 

UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;

获取当前设备方向。注意:必须在调用beginGeneratingDeviceOrientationNotifications方法后,此orientation属性才有效,否则一直是0

所以一般设备旋转监听后加上:


[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
4.实现方案
4.1 逐级实现

一般项目中会涉及三种控制器:UITabBarController , UINavigationController ,UIViewController。

项目一般使用UITabBarController作为UIWindow的根视图控制器,UITabBarController管理着若干个导航控制器UINavigationController,导航控制器管理着其下面的UIViewController。屏幕旋转控制的优先级为:

UITabBarController → UINavigationController → UIViewController。如果高优先级的控制器关闭了屏幕自动旋转或者只支持竖屏显示,低优先级控制器则无法自动旋转或横屏显示。

若想当前UIViewController进行屏幕旋转控制,则需要重写UITabBarController和UINavigationController中的屏幕旋转的是三个方法,让其响应当前UIViewController的控制。

UITabBarController

UINavigationController

之后就可以在当前ViewController中,重写这三个属性的get方法,来控制页面页面是否支持屏幕旋转,支持的方向以及初始显示方向。

另外,若从一个竖屏页面跳转横屏页面,会发现页面并没有横屏显示。这时需要我们手动设置设备方向,既使用NSInvocation对象给[UIDevice currentDevice]发setOrientation消息,强制改变屏幕方向。
4.2 使用模态视图

1.在AppDelegate中新增一个属性,用来控制当前支持的屏幕方向:

在竖屏页面不需要设置isForceLandscape的值,当通过presenter跳转横屏页面时,在viewDidLoad中,设置其值为YES。当要返回上一页面时,再重新设置其值为NO。

4.3 将View旋转90度

这种方式思路比较简单,

1.当需要横屏时,首先把需要横屏的view从superView中移除,添加到keyWindow上,然后做一个旋转90度的动画。

2.当需要从横屏切换至竖屏时,先做一个反向旋转90度的动画,然后把该view从keyWindow上移除,添加到之前的superView上。

注意:每次切换晚之后,需要把状态栏方向切换至对应的横竖屏方向。

以上是关于iOS屏幕旋转技术点及解决方案总结的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 真正可以监听屏幕旋转的插件

iOS----应用的旋转---Orientations

android--屏幕旋转方法总结

iOS学习笔记— 屏幕旋转

IOS屏幕旋转

iOS 8 自动旋转将图像旋转到屏幕外