写在前面
方向旋转在日常App上基本都会用到,用的时候可能会因为赶工期而以实现功能为主,认真思考了为啥去这样做有没有bug或者后续的开发中是否还会用到。不只是屏幕旋转,还有其他的东西也是这样,导致之前做的时候感觉也会了,实际开发的时候,有时就会像喝断片一样。
此文的目的是为了加深理解和巩固一下知识记忆,另外此文也附带了对屏幕旋转的一些理解和一些需要注意的地方,小心驶得万年船哇。
三个方向的枚举
1.UIDeviceOrientation:是描述设备的方向,含有以下值:
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait, // 竖立
UIDeviceOrientationPortraitUpsideDown, // 倒竖
UIDeviceOrientationLandscapeLeft, // 横屏,home键在右边
UIDeviceOrientationLandscapeRight, // 横屏,home键在左边
UIDeviceOrientationFaceUp, // 屏幕朝上
UIDeviceOrientationFaceDown // 屏幕朝下
其中UIDeviceOrientationLandscapeLeft可以这样理解:以home键或Home Indicator(下文仅用home键形容同等)为参照物,UIDeviceOrientationLandscapeRight就是设备向右旋转了,所以home键在左侧。反之亦然。
2。UIInterfaceOrientation:描述的是页面的方向,含有以下值:
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown,
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
其中之所以UIInterfaceOrientationLandscapeLeft和UIDeviceOrientationLandscapeRight等价,就是因为设备旋转后,页面需要向反方向旋转才能符合正常使用的规范。
3 UIInterfaceOrientationMask: 作用是在指定的视图控制器中支持的页面多种方向的集合,含有以下值
UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
第一个枚举是用来描述设备的方向;第二个枚举是用来描述页面的方向;第三个枚举则是用来描述页面可支持的方向集合。另外设备面朝上和朝下两种情况通常不做考虑。
获取设备的方向
1 可以通过获取设备的orientation属性值来判断当前设备的方向。
2 有些时候需要通过监听来获取设备的方向,需要通过使用通知来监听,但是有个注意的地方就是从设备方向改变的通知中获取数据前后需要调用一对方法:
beginGeneratingDeviceOrientationNotifications和endGeneratingDeviceOrientationNotifications
// 通过通知名:UIDeviceOrientationDidChangeNotification 来获取
// 调用生成设备方向变化的通知方法
[[NSNotificationCenter defaultCenter] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeOrientation) name:UIDeviceOrientationDidChangeNotification object:nil];
// ...
// 移除通知前需调用结束生成设备方向变化的通知
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self];
3 有点需要非常注意的是:如果用户在控制栏锁定了屏幕方向,收不到方向改变的通知,包括即使你所在的试图控制器支持多个方向,也只会强转第一个方向。
4 还有一点就是状态栏的问题,如果没有设置状态的样式,在强转横屏时将会隐藏状态栏。
5 另外使用此种方式时可能会收到状态UIDeviceOrientationUnknown,比如第一次进入app的过程中以及只支持竖屏的情况时,但是一般跳转时会有几次的方向回调的,当出现这个状态时可以返回竖屏的状态。
设备旋转的设置的几种方式
1 因为设备支持的方向旋转有几种方式
项目工程的设置:在工程的General和info.plist中设置都是一样的,因为数据都存储在info.plist中
AppDelegate中的设置:通过在代理中- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window设置支持的方向。
单个视图控制控制器的设置:需要其父控制器UITabBarController或UINavigationController也支持当前控制器的方向才行。
2 上述方式设置可以简单理解为:项目工程的设置为App默认设置;AppDelegate中的设置为你当前设置的,所以会覆盖项目工程的设置;而单个视图控制器的设置为当前页面设置,但是受AppDelegate中的影响。
3 默认创建应用将会默认勾选除 Portrait Upside down这个选项外的方向。
4 即使你一个都不勾选,应用还是会默认以 Portrait 的方式。