一、屏幕旋转机制:

  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. ROC曲线和PR曲线绘制【转】

    TPR=TP/P :真正率:判断对的正样本占所有正样本的比例.  Precision=TP/(TP+FP) :判断对的正样本占判断出来的所有正样本的比例 FPR=FP/N :负正率:判断错的负样本占所 ...

  2. http的无状态无连接

    搞爬虫的核心:http协议. 在理解http中的无状态和无连接时,有一些困惑,下文可以解决. 转自:http://www.cnblogs.com/bellkosmos/p/5237146.html h ...

  3. Make a Crystal UVA - 11014 (容斥定理)

    题意:给定一个NxNxN的正方体,求出最多能选几个整数点,使得任意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O),那么所 ...

  4. Windows下python 3.0版本django的安装、配置、与启动

    使用的环境是Windows操作系统,python的环境是3.6,django是官网上最新的版本1.10.6,本文介绍从安装python之后怎样用过pip管理工具安装django,以及django的项目 ...

  5. 【题解】HAOI2018染色

    好坑啊不开心…… 其实这题的想法还是比较简单粗暴的.题目明示恰好xxx,显然排除斜率二分这个玩意儿,那么不就只剩下容斥了嘛…… 令 \(A_{x}\) 为恰好出现了 \(S\) 次的至少有 \(x\) ...

  6. kafka问题集(二):__consumer_offsets topic的分区中有一个分区数据很多,多达1T

    仅个人实践中所遇到的问题,若有不对的,欢迎交流! 一.场景描述 kafka集群中有几台突然挂了,后台日志显示设备空间满了,消息无法写入__consumer_offsets topic的分区中了.查看k ...

  7. Android Studio中多项目共享Library

    FAQ: as的projectA中有一个commonLib的源码库模块,projectB要调用其中的commonLib, 这个有没有方案?不用手动拷贝aar的   方案1. 采用gradle配置参数方 ...

  8. 【codeforces gym】Increasing Costs

    Portal --> Increasing Costs Description 给你一个\(n\)个点无重边无自环的无向连通图,每条边有一个边权,对于每一条边,询问去掉这条边之后有多少个点到\( ...

  9. 【最大流/二分图匹配】【网络流24题】【P3254】 圆桌问题

    Description 假设有来自m 个不同单位的代表参加一次国际会议.每个单位的代表数分别为ri (i =1,2,--,m). 会议餐厅共有n 张餐桌,每张餐桌可容纳ci (i =1,2,--,n) ...

  10. centos systemctl daemon-reload 提示 no such file or directory 的一个原因

    service 的文件名写错了 比如 mongodb.service 写成了 mongodb.srvice 真的是坑,居然没有提示具体的路径,只是提示一个 no such file or direct ...