加速计是整个IOS屏幕旋转的基础,依赖加速计,设备才可以判断出当前的设备方向,IOS系统共定义了以下七种设备方向:

typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
    UIDeviceOrientationUnknown,
    UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom
    UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top
    UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right
    UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left
    UIDeviceOrientationFaceUp,              // Device oriented flat, face up
    UIDeviceOrientationFaceDown             // Device oriented flat, face down
};

  以及如下四种界面方向:

typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
};
 

一、UIKit处理屏幕旋转的流程 

  当加速计检测到方向变化的时候,会发出 UIDeviceOrientationDidChangeNotification 通知,这样任何关心方向变化的view都可以通过注册该通知,在设备方向变化的时候做出相应的响应。

  UIKit的相应屏幕旋转的流程如下:

1、设备旋转的时候,UIKit接收到旋转事件。

2、UIKit通过AppDelegate通知当前程序的window。

3、Window会知会它的rootViewController,判断该view controller所支持的旋转方向,完成旋转。

4、如果存在弹出的view controller的话,系统则会根据弹出的view controller,来判断是否要进行旋转。

二、UIViewController实现屏幕旋转

  在响应设备旋转时,我们可以通过UIViewController的方法实现更细粒度的控制,当view controller接收到window传来的方向变化的时候,流程如下:

1、首先判断当前viewController是否支持旋转到目标方向,如果支持的话进入流程2,否则此次旋转流程直接结束。

2、调用 willRotateToInterfaceOrientation:duration: 方法,通知view controller将要旋转到目标方向。如果该viewController是一个container view controller的话,它会继续调用其content view controller的该方法。这个时候我们也可以暂时将一些view隐藏掉,等旋转结束以后在现实出来。

3、window调整显示的view controller的bounds,由于view controller的bounds发生变化,将会触发 viewWillLayoutSubviews 方法。这个时候self.interfaceOrientation和statusBarOrientation方向还是原来的方向。

4、接着当前view controller的 willAnimateRotationToInterfaceOrientation:duration: 方法将会被调用。系统将会把该方法中执行的所有属性变化放到动animation block中。

5、执行方向旋转的动画。

6、最后调用 didRotateFromInterfaceOrientation: 方法,通知view controller旋转动画执行完毕。这个时候我们可以将第二部隐藏的view再显示出来。

  整个响应过程如下图所示:

  

  以上就是UIKit下一个完整的屏幕旋转流程,我们只需要按照提示做出相应的处理就可以完美的支持屏幕旋转。

三、注意事项和建议

  1)注意事项

  当我们的view controller隐藏的时候,设备方向也可能发生变化。例如view Controller A弹出一个全屏的view controller B的时候,由于A完全不可见,所以就接收不到屏幕旋转消息。这个时候如果屏幕方向发生变化,再dismiss B的时候,A的方向就会不正确。我们可以通过在view controller A的viewWillAppear中更新方向来修正这个问题。

  2)屏幕旋转时的一些建议

  • 在旋转过程中,暂时界面操作的响应。
  • 旋转前后,尽量保持当前显示的位置不变。
  • 对于view层级比较复杂的时候,为了提高效率在旋转开始前使用截图替换当前的view层级,旋转结束后再将原view层级替换回来。
  • 在旋转后最好强制reload tableview,保证在方向变化以后,新的row能够充满全屏。例如对于有些照片展示界面,竖屏只显示一列,但是横屏的时候显示列表界面,这个时候一个界面就会显示更多的元素,此时reload内容就是很有必要的。

  注:以上内容和插图全部来自苹果官方文档:View Controller Programming Guide for iOS

【转】IOS设备旋转的内部处理流程以及一些【优化建议】的更多相关文章

  1. Mac平台下部署UE4工程到iOS设备的流程

    1.开发环境 UE4.Xcode.iOS版本情况如下: 1.UE4:当前最新版本Unreal Engine 4.17.2. 2.Xcode:当前最新版本Xcode9.0. 3.iOS:当前最新版本iO ...

  2. 不通过App Store,在iOS设备上直接安装应用程序(转)

    今天在iOS设备上安装天翼云存储app,在safari上直接打开http://cloud.189.cn/wap/index.jsp,点击“点击免费安装”,如下图: 神奇的事情发生了,设备上直接下载ap ...

  3. 【转】使IFRAME在iOS设备上支持滚动

    原文链接: Scroll IFRAMEs on iOS原文日期: 2014年07月02日 翻译日期: 2014年07月10日翻译人员: 铁锚 很长时间以来, iOS设备上Safari中超出边界的元素将 ...

  4. 使IFRAME在iOS设备上支持滚动

    原文链接: Scroll IFRAMEs on iOS原文日期: 2014年07月02日 翻译日期: 2014年07月10日翻译人员: 铁锚很长时间以来, iOS设备上Safari中超出边界的元素将不 ...

  5. Samsung_tiny4412(驱动笔记03)----字符设备驱动基本操作及调用流程

    /*********************************************************************************** * * 字符设备驱动基本操作及 ...

  6. iOS设备的标识---UUID和IDFA

    一:1.1 :UDID 简介:UDID的全称是Unique Device Identifier,顾名思义,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和数字组成.在很多需要限制一台设备一个账 ...

  7. 怎样将游戏从Unity导到iOS设备上

    当我开始开发自己的iOS游戏时,我会考虑的第一件事便是如何将其导出到设备中,如此有效地测试我的游戏.最初,该过程看似很长且复杂,我所遇到的主要问题是,尽管存在许多资源,但是它们并非完全来自同样的地方, ...

  8. 分析Tapjoy的模式—分发用于ios设备的企业级应用程序

    下面简单介绍下Tapjoy的模式,供大家参考: Tapjoy最初的合作模式:“按安装奖励”(pay-per-install) Tapjoy利用非常成功的奖励性下载模式影响了App Store的免费游戏 ...

  9. 设备旋转,创建水平模式布局--Android studio

    1.在项目工具窗口中,右键单击res目录后选择new--Android resource directory菜单项. 2.从资源类型Resource type列表中选择layout,保持Source ...

随机推荐

  1. how to create a framework for ios . cool!

    预热. http://www.raywenderlich.com/65964/create-a-framework-for-ios http://insert.io/framework-ios8-xc ...

  2. [c++] Collection of key and difficult points

    Operator Overload 1. 在重载下标运算符时(数组符号):不可重载为友元函数,必须是非static类的成员函数. why 2. overload ++ 时,如果是:   int a;  ...

  3. [转载]在线文档预览方案-Office Web Apps

    最近在做项目时,要在手机端实现在线文档预览的功能.于是百度了一下实现方案,大致是将文档转换成pdf,然后在通过插件实现预览.这些方案没有具体实现代码,也没有在线预览的地址,再加上项目时间紧迫.只能考虑 ...

  4. 高效查看MySQL帮助文档的方法

    在mysql的使用过程中, 可能经常会遇到以下问题: 某个操作语法忘记了, 如何快速查找? 如何快速知道当前版本上某个字段类型的取值范围? 当前版本都支持哪些函数?希望有例子说明.. 当前版本是否支持 ...

  5. js-基础(1)

    js-基础(1) javascript由三部分组成:核心,DOM,BOM核心——ECMAScript,可以运行浏览器/单纯的JS引擎    console.log(‘hello’);DOM——操作HT ...

  6. thread_CyclicBarrier回环栅栏

    CyclicBarrier回环栅栏,字面意思是可循环使用(Cyclic)的屏障(Barrier).通过它可以实现让一组线程等待至某个状态之后再全部同时执行. 它要做的事情是,让一组线程到达一个屏障(也 ...

  7. Linux各版本的本地root密码破解方法

    (一)RedHat/CentOS/Fedora 系统密码破解 1.在grub选项菜单按E进入编辑模式 2.编辑kernel 那行最后加上S (或者Single) 3.按B,启动到single-user ...

  8. [水煮 ASP.NET Web API2 方法论](3-2)直接式路由/属性路由

    问题 怎么样可以使用更贴近资源(Controller,Action)的方式定义路由. 解决方案 可以使用属性路由直接在资源级别声明路由.只要简单的在 Action 上使用属性路由 RouteAttri ...

  9. MVC视图展现模式之移动布局

    参考:http://www.cnblogs.com/dunitian/p/5218140.html 简单点,直接上用法 新建MVC项目,在golbal.asax中添加如下代码 //添加一个自定义后缀 ...

  10. 用UltraISO制作支持windows 7的U盘启动盘

    用UltraISO制作U盘启动盘,有人写过,我也看过,不过依照网上的那些文章,成功的并不多,经过几次试验,在不同的主板环境下成功概率高的方法应该如下:   1. UltraISO建议9.3以上 2. ...