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上。
注意:每次切换晚之后,需要把状态栏方向切换至对应的横竖屏方向。