一、屏幕旋转机制:

  iOS通过加速计判断当前的设备方向和屏幕旋转。当加速计检测到方向变化的时候,屏幕旋转的流程如下:

  1、设备旋转时,系统接收到旋转事件。

  2、系统将旋转事件通过AppDelegate通知当前的主Window。

  3、window通知它的rootViewController。

4、rootViewController判断所支持的旋转方向,完成旋转。

  iOS系统中屏幕旋转事件没有像触碰事件那样进行hitTest,所以只有rootViewController才能接收到屏幕旋转的事件,在其他viewController中实现旋转控制方法是不会被调用的。当屏幕旋转时应用程序会发出UIDeviceOrientationDidChangeNotification通知,这样任何关系方向变化的view都可以通过注册该通知,在设备方向发生变化的时候发生响应。

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

  1、首先判断当前viewController是否支持旋转到目标方向,如果支持则继续,否则流程就此结束。

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

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

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

  5、执行屏幕旋转动画。

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

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

  

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

二、旋转机制实现

  iOS5屏幕旋转控制

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}

  返回YES就是允许旋转,NO就是不允许

  根据toInterfaceOrientation 可以控制屏幕允许旋转的方向,比如不支持Home按钮朝上这种屏幕方向。代码如下:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
 if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
return NO;
}
return YES;
}

  

  这种方法已经被苹果列为deprecated。但为了兼容iOS5及以前的版本还需要继续实现。

  iOS6屏幕旋转控制

  - (BOOL)shouldAutorotate  默认返回YES,当为YES时允许转屏,否则为不允许。

  - (NSUInteger)supportedInterfaceOrientations 决定可以转哪个方向。如果所有方向都支持返回 UIInterfaceOrientationMaskAll,如果不允许Home键朝上返回UIInterfaceOrientationMaskAllButUpsideDown。

三、注意事项

  1、旋屏后的frame

  如果直接把window.rootviewController = (UIViewController*)vc;旋屏的时候vc的frame一直都是保持竖屏状态,bounds是正确的。
  如果使用UINavigationController的rootviewControoler 设置为vc,然后那NavigationControllerView去作为window的rootView,在旋屏的时候会发现vc的frame和bounds都是正确的。
  结论:判断屏幕尺寸用bounds比frame更准确。
 
  2、如果viewController或者view是隐藏状态的话就接收不到屏幕旋转事件,那么重新显示就会有问题。可以通过 viewWillAppear 函数解决这个问题。
  3、屏幕旋转的时候,让界面暂时不响应事件。
  4、对于view层级比较复杂的视图,使用截图替换当前的视图,旋转完成后再替换回原来的视图。
  5、旋转后调用tableview的reload方法,保证屏幕尺寸变化后cell可以充满全屏。

iOS学习笔记(3)— 屏幕旋转的更多相关文章

  1. iOS学习笔记-自己动手写RESideMenu

    代码地址如下:http://www.demodashi.com/demo/11683.html 很多app都实现了类似RESideMenu的效果,RESideMenu是Github上面一个stars数 ...

  2. iOS学习笔记-自定义过渡动画

    代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...

  3. iOS学习笔记——AutoLayout的约束

    iOS学习笔记——AutoLayout约束 之前在开发iOS app时一直以为苹果的布局是绝对布局,在IB中拖拉控件运行或者直接使用代码去调整控件都会发上一些不尽人意的结果,后来发现iOS在引入了Au ...

  4. iOS学习笔记-精华整理

    iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...

  5. iOS学习笔记总结整理

    来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...

  6. IOS学习笔记07---C语言函数-printf函数

    IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...

  7. iOS学习笔记之触摸事件&UIResponder

    iOS学习笔记之触摸事件&UIResponder 触摸事件 与触摸事件相关的四个方法如下: 一根手指或多根手指触摸屏幕 -(void)touchesBegan:(NSSet *)touches ...

  8. IOS学习笔记48--一些常见的IOS知识点+面试题

      IOS学习笔记48--一些常见的IOS知识点+面试题   1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...

  9. iOS学习笔记-地图MapKit入门

    代码地址如下:http://www.demodashi.com/demo/11682.html 这篇文章还是翻译自raywenderlich,用Objective-C改写了代码.没有逐字翻译,如有错漏 ...

  10. iOS学习笔记22-推送通知

    一.推送通知 推送通知就是向用户推送一条信息来通知用户某件事件,可以在应用退到后台后,或者关闭后,能够通过推送一条消息通知用户某件事情,比如版本更新等等. 推送通知的常用应用场景: 一些任务管理APP ...

随机推荐

  1. Dubbo学习(五) Dubbo 从下载到编译成功

    DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广 ...

  2. 笔记:delphi 与 Query

    以下不保存证正确 Query用SQL语言执行过的,没有必要Cancel.Post,因为其会对数据库直接操作:执行Update.Insert.Delete请用SQL语句: 用Table使用对当前记录直接 ...

  3. 【BZOJ4025】二分图(线段树分治,并查集)

    [BZOJ4025]二分图(线段树分治,并查集) 题面 BZOJ 题解 是一个二分图,等价于不存在奇环. 那么直接线段树分治,用并查集维护到达根节点的距离,只计算就好了. #include<io ...

  4. 跟踪分析Linux内核的启动过程--20135334赵阳林

    解决ubuntu下make menuconfig错误问题 http://blog.sina.com.cn/s/blog_726684020100r1oo.html 安装好相关的软件之后,键入make ...

  5. 什么是 metadata (元数据)

    1. 什么是元数据 任何文件系统中的数据分为数据和元数据.数据是指普通文件中的实际数据,而元数据指用来描述一个文件的特征的系统数据,诸如访问权限.文件拥有者以及文件数据块的分布信息(inode...) ...

  6. mysqlbinlog- 处理二进制日志文件的实用工具 学习笔记

    参考 MySQL 5.5官方简体中文参考手册完美版  8.6 节 调用: shell> mysqlbinlog [option] log-files... mysqlbinlog支持下面选项: ...

  7. 项目开发中git常用命令、git工作流、git分支模型

    #新建代码库git init # 在当前目录新建一个Git代码库git init [project-name] # 新建一个目录,将其初始化为Git代码库git clone [url] # 下载一个项 ...

  8. linux Git版本控制学习与Git服务器搭建

    来源地址 要随时掌握工作区的状态,使用git status命令. 如果git status告诉你有文件被修改过,用git diff可以查看修改内容. 初始化一个Git仓库,使用git init命令. ...

  9. 野指针(Wild pointer)和悬垂指针(dangling pointer)

    详细参考如下: Dangling pointer(悬垂指针.迷途指针)和 Wild pointer(野指针) 迷途指针经常出现在混杂使用malloc() 和 free() 库调用: 当指针指向的内存释 ...

  10. Linux运维五:定时任务crond服务

    一.crond简介 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动cro ...