iOS屏幕旋转 浅析
一、两种orientation
了解屏幕旋转首先需要区分两种orientation
1、device orientation
设备的物理方向,由类型UIDeviceOrientation
表示,当前设备方向获取方式:
1 |
|
该属性的值一般是与当前设备方向保持一致的,但须注意以下几点:
①文档中对该属性的注释:
1 |
|
所以更推荐下面这种用法:
1 |
|
②系统横竖屏开关关闭时
如果关闭了系统的横竖屏切换开关,即系统层级只允许竖屏时,再通过上述方式获取到的设备方向将永远是UIDeviceOrientationUnknown
。可以通过Core Motion
中的CMMotionManager
来获取当前设备方向。
2、interface orientation
界面显示的方向,由类型UIInterfaceOrientation
表示。当前界面显示方向有以下两种方式获取:
1 |
|
即可以通过系统statusBar的方向或者viewController的方向来获取当前界面方向。
3、二者区别
通过UIDevice
获取到的设备方向在手机旋转时是实时的,通过UIApplication
的statusBar或者viewController获取到的界面方向在下述方法:
1 |
|
调用以后才会被更改成最新的值。
二、相关枚举定义
1、UIDeviceOrientation:
1 |
|
2、UIInterfaceOrientation:
1 |
|
从宏定义可知,device方向比interface多了两个定义:UIDeviceOrientationFaceUp
和UIDeviceOrientationFaceDown
,分别表示手机水平放置,屏幕向上和屏幕向下。
三、相关方法
1、iOS5中控制屏幕旋转的方法:
1 |
|
如果打算支持toInterfaceOrientation对应的方向就返回YES,否则返回NO。
2、iOS6中控制屏幕旋转相关方法:
1 |
|
第一个方法决定是否支持多方向旋转屏,如果返回NO则后面的两个方法都不会再被调用,而且只会支持默认的UIInterfaceOrientationMaskPortrait方向;
第二个方法直接返回支持的旋转方向,该方法在iPad上的默认返回值是UIInterfaceOrientationMaskAll
,iPhone上的默认返回值是UIInterfaceOrientationMaskAllButUpsideDown
,详情见官方Q&A文档;
第三个方法返回最优先显示的屏幕方向,比如同时支持Portrait和Landscape方向,但想优先显示Landscape方向,那软件启动的时候就会先显示Landscape,在手机切换旋转方向的时候仍然可以在Portrait和Landscape之间切换;
3、attemptRotationToDeviceOrientation方法
从iOS5开始有了这个新方法:
1 |
|
该方法的使用场景是interface orientation和device orientation不一致,但希望通过重新指定interface orientation的值,立即实现二者一致;如果这时只是更改了支持的interface orientation的值,没有调用attemptRotationToDeviceOrientation,那么下次device orientation变化的时候才会实现二者一致,关键点在于能不能立即实现。
举个例子:
假设当前的interface orientation只支持Portrait,如果device orientation变成Landscape,那么interface orientation仍然显示Portrait;
如果这时我们希望interface orientation也变成和device orientation一致的Landscape,以iOS6为例,需要先将supportedInterfaceOrientations的返回值改成Landscape,然后调用attemptRotationToDeviceOrientation方法,系统会重新询问支持的interface orientation,已达到立即更改当前interface orientation的目的。
四、如何决定interface orientation
1、全局控制
Info.plist文件中,有一个Supported interface orientations
,可以配置整个应用的屏幕方向,此处为全局控制。
2、UIWindow
iOS6的UIApplicationDelegate提供了下述方法,能够指定 UIWindow 中的界面的屏幕方向:
1 |
|
该方法默认值为Info.plist中配置的Supported interface orientations
项的值。
iOS中通常只有一个window,所以此处的控制也可以视为全局控制。
3、controller
只有以下两种情况:
- 当前controller是window的rootViewController
- 当前controller是modal模式的
时,orientations相关方法才会起作用(才会被调用),当前controller及其所有的childViewController都在此作用范围内。
4、最终支持的屏幕方向
前面所述的3种控制规则的交集就是一个controller的最终支持的方向;
如果最终的交集为空,在iOS6以后会抛出UIApplicationInvalidInterfaceOrientationException
崩溃异常。
四、强制屏幕旋转
如果interface和device方向不一样,想强制将interface旋转成device的方向,可以通过attemptRotationToDeviceOrientation实现,但是如果想将interface强制旋转成任一指定方向,该方式就无能为力了。
不过聪明的开发者们总能想到解决方式:
1、私有方法
1 |
|
但是现在苹果已经将该方法私有化了,越狱开发的同学可以试试,或者自己想法子骗过苹果审核吧。
2、旋转view的transform
也可以通过旋转view的transform属性达到强制旋转屏幕方向的目的,但个人感觉这不是靠谱的思路,可能会带来某些诡异的问题。
3、主动触发orientation机制
要是能主动触发系统的orientation机制,调用orientation相关方法,使新设置的orientation值起作用就好了。这样只要提前设置好想要支持的orientation,然后主动触发orientation机制,便能实现将interface orientation旋转至任意方向的目的。
万能的stackoverflow上提供了一种主动触发的方式:
在iOS4和iOS6以后:
1 |
|
iOS5中:
1 |
|
这种方式会触发UIKit重新调用controller的orientation相关方法,以达到在device方向不变的情况下改变interface方向的目的。
虽然不优雅,但却能解决问题,凑合吧。。
PS:
话说iOS8中的屏幕旋转相关方法又变化了,表示适配起来很蛋疼。。。
五、参考文档
- Why won’t my UIViewController rotate with the device?;
- How to force a UIViewController to Portait orientation in iOS 6
- IOS Orientation, 想怎么转就怎么转
- iOS 屏幕方向那点事儿
转自:http://foggry.com/blog/2014/08/08/ping-mu-xuan-zhuan-xue-xi-bi-ji/
iOS屏幕旋转 浅析的更多相关文章
- 【转】IOS屏幕旋转与View的transform属性之间的关系,比较底层
iTouch,iPhone,iPad设置都是支持旋转的,如果我们的程序能够根据不同的方向做出不同的布局,体验会更好. 如何设置程序支持旋转呢,通常我们会在程序的info.plist中进行设置Suppo ...
- IOS屏幕旋转思路和实践
这段时间同事在做一个直播项目,项目有个需求:一个界面需要手动设置屏幕的方向,设置好之后方向不能变化.完成这个需求花了特别大的精力,归因是网上关于屏幕旋转的知识比较凌乱,解决问题花费不少时间,最后决定把 ...
- ios 屏幕旋转的问题
在ios6之前我们旋转屏幕只需要实现shouldAutorotateToInterfaceOrientation就行了 - (BOOL)shouldAutorotateToInterfaceOrien ...
- iOS 屏幕旋转 nav+tabbar+present(网页) 2016
如题,最近一个app架构为 nav + tabbar ,需求是 在点击tabbar中的一个菜单项时,弹出网页,该网页需要横屏显示,其他页面不变 都保持竖屏. XCode Version 7.2.1 ...
- iOS屏幕旋转
三种方法 需求:全局主要是竖屏 个别界面需要横屏
- 【转】IOS设备旋转的内部处理流程以及一些【优化建议】
加速计是整个IOS屏幕旋转的基础,依赖加速计,设备才可以判断出当前的设备方向,IOS系统共定义了以下七种设备方向: typedef NS_ENUM(NSInteger, UIDeviceOrienta ...
- iOS实现屏幕旋转
iOS实现屏幕旋转有两种方式 1. 应用本身支持 2. 手动旋转UIView (这种方式我没找到旋转 系统控件的方法 如:键盘.导航.UIAlertView) 如果你只是要把竖屏的播放器,做成支持横屏 ...
- ios实现屏幕旋转的方法
1.屏蔽AppDelegate下面的屏幕旋转方法 #pragma mark - 屏幕旋转的 //- (UIInterfaceOrientationMask)application:(UIApplica ...
- 监听iOS检测屏幕旋转状态,不需开启屏幕旋转-b
-(void)rotation_icon:(float)n { UIButton *history_btn= [self.view viewWithTag:<#(NSInteger)#>] ...
随机推荐
- 团队项目(spring会议)
[例会时间]2014/4/11 [例会地点]一教213课堂上 [例会形式]小组讨论 [例会主持]马翔 [例会记录]兰梦 在这次会议上,我们针对我们的项目进行了分割,并分别认领各自的任务 下面是任务的认 ...
- 简单学习JavaScript面向对象编程
JavaScript是一种弱类型语言.有一种原型机制. 1.创建一个空对象:var bill = {}; 给这个对象添加属性和方法: bill.name = "Bill E Goat&quo ...
- PHP 流程
登录页面 <body> <form action="loginchuli.php" method="post"> <div> ...
- 使用timer定时器,防止事件重入
首先简单介绍一下timer,这里所说的timer是指的System.Timers.timer,顾名思义,就是可以在指定的间隔是引发事件.官方介绍在这里,摘抄如下: 1 2 Timer 组件是基于服务器 ...
- Quartz(任务调度)- 入门学习
参照:http://blog.csdn.net/szwangdf/article/details/6158646 1.自定义定时任务管理类 QuartzManager 参照大神基础上新增:1.添加jo ...
- pc打开手机站提示切换为手机屏幕
.turn { position: absolute; width: 100%; height: 100%; left:; top:; background: url(../images.png) c ...
- 关于perl闭包(个人理解)
我个人理解,就是当一个变量超出作用域时,应是消失了,不见了的,但你还能访问它,这就是闭包. # #看下面的例子. #!/usr/bin/env perl -w use strict; { my $va ...
- 移动端Click300毫秒点击延迟的来龙去脉(转)
原文地址:What Exactly Is….. The 300ms Click Delay 快速响应是所有 UI 实现的重中之重.研究表明,当延迟超过 100 毫秒,用户就能感受到界面的卡顿. 然而, ...
- Educational Codeforces Round 15_D. Road to Post Office
D. Road to Post Office time limit per test 1 second memory limit per test 256 megabytes input standa ...
- HDU2206:IP的计算
Problem Description 在网络课程上,我学到了很多有关IP的知识.IP全称叫网际协议,有时我们又用IP来指代我们的IP网络地址,现在IPV4下用一个32位无符号整数来表示,一般用点分方 ...