一、概述:

    在iOS应用中,由UIViewController来控制屏幕翻转,根据需要随设备方向自动切换。在iOS6和之前的系统之间,控制方法发生了些变化。
二、视图伸缩属性:
1.UIView类的autoresizingMask属性,用来指定当它的父视图frame发生变化时,自身frame的变化规则。此属性可以在XIB中设置,也可以直接用代码设置,具体用哪个看情况。可用值的具体含义如下:
   (1)UIViewAutoresizingNone:自身frame不随父视图变化;
   (2)UIViewAutoresizingFlexibleLeftMargin:父视图frame发生变化时,自身视图的左边距动态缩小或者拉伸;
   (3)UIViewAutoresizingFlexibleRightMargin:父视图frame发生变化时,自身视图的右边距动态缩小或者拉伸;
   (4)UIViewAutoresizingFlexibleTopMargin:父视图frame发生变化时,自身视图的上边距动态缩小或者拉伸;
   (5)UIViewAutoresizingFlexibleBottomMargin:父视图frame发生变化时,自身视图的下边距动态缩小或者拉伸;
   (6)UIViewAutoresizingFlexibleWidth:父视图frame发生变化时,自身视图宽度随父视图同比例动态缩小或者拉伸;
   (7)UIViewAutoresizingFlexibleHeight:父视图frame发生变化时,自身视图高度随父视图同比例动态缩小或者拉伸;
2.伸缩属性可以多个一起使用,使用位或运算符("|")连接。
3.在屏幕翻转之后,控制器的主视图的frame会发生变化,所以,在屏幕翻转之后的界面调整中,可能会用到这个属性来控制子界面的frame。
三、Info.plist中相关的设置:
Supported interface orientations,对应一个数组,包含应用支持的设备方向。如果代码中实现了没有支持的方向,执行时会报异常。
四、UIViewController中的翻转控制方法(iOS6之前)
1.判断是否支持新方向:
(1)实现视图控制器类的shouldAutorotateToInterfaceOrientation:方法,在此方法中,如果当前设备方向为我们需要支持的方向,则该方法返回YES,否则返回NO。系统会根据此方法返回的BOOL值来决定是不是翻转该控制器的界面。
(2)可用的设备方向值如下:
   UIInterfaceOrientationPortrait:Home键在下方;
   UIInterfaceOrientationPortraitUpsideDown:Home键在上方;
   UIInterfaceOrientationLandscapeLeft:Home键在左方:
   UIInterfaceOrientationLandscapeRight:Home键在右方。
(3)此方法默认实现只支持UIInterfaceOrientationPortrait。
2.翻转通知方法:
   (1)控制器类翻转通知分为两类,一类是一步翻转通知,一类是两步翻转通知。
   (2)控制器默认选择使用一步翻转过程,如果同时重写了两步翻转通知方法,则控制器会自动选择使用两步翻转过程。
3.一步翻转通知方法:
(1)视图控制器类的willRotateToInterfaceOrientation:duration:方法,在控制器视图将要翻转时被调用。
    如果视图翻转时界面变化相对简单,可以在XIB中使用伸缩属性来设置子界面变化。如果在翻转之后界面变化比较复杂,伸缩属性就无能为力了,需要在此方法中用代码动态设置需要调整的子视图的frame。在改变子视图frame时,为了使翻转效果更友好,应该使用动画API,使frame调整过程更优美,动画执行时长使用duration参数对应的值。
(2)视图控制器类的didRotateFromInterfaceOrientation:方法,在控制器视图翻转完毕时调用。
    我们可以在此方法中做一些必要的动作。
    不要在此方法中调整子视图frame,否则子视图的界面frame调整会比主视图慢一小段时间,效果不好。
4.两步翻转通知方法:
(1)视图控制器类的willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:方法,当视图控制器前半部分翻转开始时调用。假如我们想要在翻转前半部分开始时添加额外的动画,可以重写此方法。
(2)视图控制器类的didAnimateFirstHalfOfRotationToInterfaceOrientation: 方法,当控制器前半部分翻转完成时调用。
(3)视图控制器类的willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:方法,当控制器后半部分翻转开始时调用。
(4)两步翻转方法在iOS5版本开始被废弃。
5.具体的执行流程:
(1)一步翻转流程图:

(2)两步翻转流程图:

五、iOS6之前使用翻转通知方法碰到的问题
1.情景简述:假如视图A,初始实现是竖屏的,而且支持所有设备方向,然后在进入视图A时,设备是横屏的,如果视图A是主视图,willRotateToInterfaceOrientation:duration:会被调用,但是如果视图A不是主视图,则不会调用,导致进入视图A之后,视图A的子视图还是竖向的状态。但是接下来真实的翻转设备到竖屏,再到横屏,willRotateToInterfaceOrientation:duration:就会被调用了。
2.分析原因:
(1)控制器初始化时,只有主视图能够收到翻转通知。但是真实的翻转设备时,已经初始化的所有视图都能收到翻转通知。主视图包含真实添加到window的控制器视图、通过presentModalViewController弹出的视图,以及导航控制器的第一个视图(之后push进的视图不是主视图)等。
(2)假如我们要写一个用导航控制器组织的App,但是每个界面都需要支持横屏和竖屏,就遇到上面的问题了。
3.解决方法:
(1)原理:重写UIView的layoutSubviews方法,当界面初始化,屏幕旋转导致重绘,都会调用此方法。
(2)实现方法:首先实现UIView的一个子类,比如取名为RotationView,并建立一个代理对象;重写layoutSubviews方法,通过检查状态栏方向是不是和之前记录的方向一致,如果不一致,则调用代理方法;然后将控制器的view属性修改为RotationView,将RotationView的代理设置为控制器本身,在代理方法实现中,根据当前设备方向,重新设置子视图frame。
(3)此方法具有通用性。
4.iOS6及以后,上面提到的问题就不存在了。但是会碰到新的问题,具体介绍下小节介绍。
六、UIViewController中的翻转控制方法(iOS6以以后)
1.视图控制器类的shouldAutorotateToInterfaceOrientation:被废弃,增加了三个新的方法来实现这个方法的功能。
(1)shouldAutorotate:返回BOOL值,告诉控制器要不要支持翻转。
(2)supportedInterfaceOrientations:如果支持翻转,则告诉控制器要支持的设备方向。
    返回值类型为NSUInteger,通过UIInterfaceOrientationMaskXXX值之间的位或运算获得。
    此方法的默认返回值为:iPad--UIInterfaceOrientationMaskAll,iPhone--UIInterfaceOrientationMaskAllButUpsideDown。
(3)preferredInterfaceOrientationForPresentation:通知控制器通过present方法导入的控制器视图支持的方向。
    返回值为类型为UIInterfaceOrientation,也就是说此方法只支持返回一个方向。苹果文档的说明:当你的主界面支持两个及以上的方向,但是希望通过present弹出的界面只支持一个方向,则重写这个方法。如果不重写这个方法,此方法会默认返回状态栏所处的方向。
2.其它翻转控制的方法,两步翻转不能用了,一步翻转和之前一样。
3.supportedInterfaceOrientations的调用时机:
(1)当用户改变设备方向时,系统会调用此方法,但是只针对window的主视图或者推进类视图的顶层视图的控制器,比如导航控制器的非顶层视图的此方法默认是不起作用的。
(2)只有shouldAutorotate返回YES时才会被调用。
4.额外操作:
(1)由于supportedInterfaceOrientations的调用时机发生了变化,所以,如果我们需要让当前显示视图来控制整体方向,需要做一些额外的操作来处理这个问题。
(2)假如window的主视图是UIViewController类,则直接重写上面的方法,返回相应支持的方向即可。
(3)假如window的主视图是导航控制器,则需要重写它,让上面的三个方法返回topViewController对应方法的返回值,即由当前显示的视图来控制整体方向。比较好的实现是使用类别的方式。
(4)加入window的主视图是选项卡控制器,则需要重写它,让上面的三个方法返回selectedViewController对应方法的返回值,即由当前选择视图来控制整体方向,如果selectedViewController为一个导航控制器,则导航控制器又会找到其topViewController返回的值。也就是说,这是一个迭代取值的过程。

iOS应用横竖屏切换相关推荐

  1. iOS 中横竖屏切换

    iOS 中横竖屏切换的功能,在开发iOS app中总能遇到.以前看过几次,感觉简单,但是没有敲过代码实现,最近又碰到了,demo尝试了几种情况,这里就做下总结. 注意 横屏两种情况是反的你知道吗? U ...

  2. iOS终极横竖屏切换解决方案

    大家的项目都是只支持竖屏的吧?大多数朋友(这其中当然也包括博主),都没有做过横屏开发,这次项目刚好有这个需求,因此把横竖屏相关的心得写成一遍文章供诸位参考. 01.综述 大多数公司的项目都只支持竖屏, ...

  3. [贝聊科技] iOS 终极横竖屏切换解决方案

    大家的项目都是只支持竖屏的吧?大多数朋友(这其中当然也包括博主),都没有做过横屏开发,这次项目刚好有这个需求,因此把横竖屏相关的心得写成一遍文章供诸位参考. 01.综述 大多数公司的项目都只支持竖屏, ...

  4. iOS视频播放横竖屏切换技巧

    一.需求:横竖屏切换. 二.效果:                       三.实现: 如上图,点击工具栏的第四个按钮进行横屏切换: - (void)toolTabButtonPressed:(A ...

  5. iOS的横竖屏切换旋转(禁自动旋转)

    这次做了视频的播放器,坑啊 ,好多,这不,刚刚爬上来,就来帮后来者填坑... 首先先说下横竖屏切换旋转的坑吧,,, 1. 在AppDelegate.h文件中 声明一个变量, @property (no ...

  6. iOS 6横竖屏切换

    iOS6.0版本之前,UIViewController之间的横竖屏切换,只需设置一个函数: - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInte ...

  7. ios 旋转屏幕试图切换_iOS屏幕横竖屏切换

    iOS屏幕横竖屏切换 胡东东博客 • 2020 年 10 月 25 日 搜了网上的教程是真的乱,废话不多说,这里从启动到具体的VC,横竖屏切换完美搞定. 如果你的app只需要支持一个方向,那么不需要看 ...

  8. iOS 横竖屏切换解决方案

    iOS 横竖屏切换解决方案 参考文章: (1)iOS 横竖屏切换解决方案 (2)https://www.cnblogs.com/qqcc1388/p/7358552.html 备忘一下.

  9. 如何解决ios横竖屏切换布局错乱的问题

    如何解决ios横竖屏切换布局错乱的问题 可以使用 location.reload(); 强制刷新页面 mounted () {// 监听 resize 方法window.addEventListene ...

最新文章

  1. 图文并茂!60页PPT《快速入门python数据分析路线》(附链接)
  2. 3.2 matlab用if语句实现选择结构
  3. lisp 任意点 曲线距离_数学篇|看完这篇,秒杀所有圆锥曲线小技巧
  4. Python实现简单的购物车
  5. 微信小程序window的配置
  6. 二 jQuery 语法
  7. 链表 python 牛客_牛客网《剑指offer》之Python2.7实现:合并两个排序的链表
  8. PHP二开美化版站长技术导航网站源码
  9. C语言模拟顺序栈的创建、入栈、出栈操作
  10. json.dumps与json.dump的区别 json.loads与json.load的区别(简洁易懂)
  11. Solr删除managedschema
  12. Linux Netfilter 防火墙模块爆新漏洞,攻击者可获取root权限
  13. [k8s]jenkins配合kubernetes插件实现k8s集群构建的持续集成
  14. Web调取摄像头拍照
  15. note2 android4.3,三星N7100/note2官方4.3原版线刷版N7100ZCUENB1
  16. 问题及解决方法记录:A component required a bean of type ‘org.springframework.web.client.RestTemplate‘ that cou
  17. 网易云热歌榜歌名与热评的高频词抓取及词云制作
  18. 操作符 算数操作符
  19. 数据清洗(一)-----------重复数据处理
  20. 爬取起点中文网小说介绍信息

热门文章

  1. 计蒜客 28437.Big brother said the calculation-线段树+二分-当前第k个位置的数 ( ACM训练联盟周赛 M)...
  2. 基于opencv的gpu与cpu对比程序,代码来自opencv的文档中
  3. 用户代码未处理EntityCommandExecutionmException报错解决方案
  4. 对于Office Live平台的思考
  5. 解决git关联的的文件颜色、小图标
  6. JavaWeb——EL表达式
  7. java 佳博打印机,佳博蓝牙打印的java 连接
  8. java语言计算器怎么写_求助,一个计算器的括号功能怎么写啊。
  9. 销售管理系统 java_用Java从零写一个B2C商城,看完不要再说自己没有实战经验了!...
  10. OpenCV学习笔记(三):多通道图像分离、混合算子:split(),merge()